/*
 * 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.annotation.NonNull;
import android.annotation.Nullable;
import android.graphics.FontFamily_Delegate.FontVariant;
import android.graphics.Paint.FontMetrics;
import android.graphics.Paint.FontMetricsInt;
import android.text.TextUtils;

import java.awt.BasicStroke;
import java.awt.Font;
import java.awt.Shape;
import java.awt.Stroke;
import java.awt.Toolkit;
import java.awt.geom.AffineTransform;
import java.util.Collections;
import java.util.List;
import java.util.Locale;
import java.util.Objects;
import java.util.stream.Collectors;
import java.util.stream.StreamSupport;

import libcore.util.NativeAllocationRegistry_Delegate;

/**
 * Delegate implementing the native methods of android.graphics.Paint
 *
 * Through the layoutlib_create tool, the original native methods of Paint 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 Paint class.
 *
 * @see DelegateManager
 *
 */
public class Paint_Delegate {
    private static final float DEFAULT_TEXT_SIZE = 20.f;
    private static final float DEFAULT_TEXT_SCALE_X = 1.f;
    private static final float DEFAULT_TEXT_SKEW_X = 0.f;

    /**
     * Class associating a {@link Font} and its {@link java.awt.FontMetrics}.
     */
    /*package*/ static final class FontInfo {
        final Font mFont;
        final java.awt.FontMetrics mMetrics;

        FontInfo(@NonNull Font font, @NonNull java.awt.FontMetrics fontMetrics) {
            this.mFont = font;
            this.mMetrics = fontMetrics;
        }
    }

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

    // ---- delegate helper data ----

    // This list can contain null elements.
    @Nullable
    private List<FontInfo> mFonts;

    // ---- delegate data ----
    private int mFlags;
    private int mColor;
    private int mStyle;
    private int mCap;
    private int mJoin;
    private int mTextAlign;
    private Typeface_Delegate mTypeface;
    private float mStrokeWidth;
    private float mStrokeMiter;
    private float mTextSize;
    private float mTextScaleX;
    private float mTextSkewX;
    private int mHintingMode = Paint.HINTING_ON;
    private int mStartHyphenEdit;
    private int mEndHyphenEdit;
    private float mLetterSpacing;  // not used in actual text rendering.
    private float mWordSpacing;  // not used in actual text rendering.
    // Variant of the font. A paint's variant can only be compact or elegant.
    private FontVariant mFontVariant = FontVariant.COMPACT;

    private int mPorterDuffMode = Xfermode.DEFAULT;
    private ColorFilter_Delegate mColorFilter;
    private Shader_Delegate mShader;
    private PathEffect_Delegate mPathEffect;
    private MaskFilter_Delegate mMaskFilter;

    @SuppressWarnings("FieldCanBeLocal") // Used to store the locale for future use
    private Locale mLocale = Locale.getDefault();

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

    @Nullable
    public static Paint_Delegate getDelegate(long native_paint) {
        return sManager.getDelegate(native_paint);
    }

    /**
     * Returns the list of {@link Font} objects.
     */
    @NonNull
    public List<FontInfo> getFonts() {
        Typeface_Delegate typeface = mTypeface;
        if (typeface == null) {
            if (Typeface.sDefaultTypeface == null) {
                return Collections.emptyList();
            }

            typeface = Typeface_Delegate.getDelegate(Typeface.sDefaultTypeface.native_instance);
        }

        if (mFonts != null) {
            return mFonts;
        }

        // Apply an optional transformation for skew and scale
        AffineTransform affineTransform = mTextScaleX != 1.0 || mTextSkewX != 0 ?
                new AffineTransform(mTextScaleX, mTextSkewX, 0, 1, 0, 0) :
                null;

        List<FontInfo> infoList = StreamSupport.stream(typeface.getFonts(mFontVariant).spliterator
                (), false)
                .filter(Objects::nonNull)
                .map(font -> getFontInfo(font, mTextSize, affineTransform))
                .collect(Collectors.toList());
        mFonts = Collections.unmodifiableList(infoList);

        return mFonts;
    }

    public boolean isAntiAliased() {
        return (mFlags & Paint.ANTI_ALIAS_FLAG) != 0;
    }

    public boolean isFilterBitmap() {
        return (mFlags & Paint.FILTER_BITMAP_FLAG) != 0;
    }

    public int getStyle() {
        return mStyle;
    }

    public int getColor() {
        return mColor;
    }

    public int getAlpha() {
        return mColor >>> 24;
    }

    public void setAlpha(int alpha) {
        mColor = (alpha << 24) | (mColor & 0x00FFFFFF);
    }

    public int getTextAlign() {
        return mTextAlign;
    }

    public float getStrokeWidth() {
        return mStrokeWidth;
    }

    /**
     * returns the value of stroke miter needed by the java api.
     */
    public float getJavaStrokeMiter() {
        return mStrokeMiter;
    }

    public int getJavaCap() {
        switch (Paint.sCapArray[mCap]) {
            case BUTT:
                return BasicStroke.CAP_BUTT;
            case ROUND:
                return BasicStroke.CAP_ROUND;
            default:
            case SQUARE:
                return BasicStroke.CAP_SQUARE;
        }
    }

    public int getJavaJoin() {
        switch (Paint.sJoinArray[mJoin]) {
            default:
            case MITER:
                return BasicStroke.JOIN_MITER;
            case ROUND:
                return BasicStroke.JOIN_ROUND;
            case BEVEL:
                return BasicStroke.JOIN_BEVEL;
        }
    }

    public Stroke getJavaStroke() {
        if (mPathEffect != null) {
            if (mPathEffect.isSupported()) {
                Stroke stroke = mPathEffect.getStroke(this);
                assert stroke != null;
                //noinspection ConstantConditions
                if (stroke != null) {
                    return stroke;
                }
            } else {
                Bridge.getLog().fidelityWarning(LayoutLog.TAG_PATHEFFECT,
                        mPathEffect.getSupportMessage(),
                        null, null, null /*data*/);
            }
        }

        // if no custom stroke as been set, set the default one.
        return new BasicStroke(
                    getStrokeWidth(),
                    getJavaCap(),
                    getJavaJoin(),
                    getJavaStrokeMiter());
    }

    /**
     * Returns the {@link PorterDuff.Mode} as an int
     */
    public int getPorterDuffMode() {
        return mPorterDuffMode;
    }

    /**
     * Returns the {@link ColorFilter} delegate or null if none have been set
     *
     * @return the delegate or null.
     */
    public ColorFilter_Delegate getColorFilter() {
        return mColorFilter;
    }

    public void setColorFilter(long colorFilterPtr) {
        mColorFilter = ColorFilter_Delegate.getDelegate(colorFilterPtr);
    }

    public void setShader(long shaderPtr) {
        mShader = Shader_Delegate.getDelegate(shaderPtr);
    }

    /**
     * Returns the {@link Shader} delegate or null if none have been set
     *
     * @return the delegate or null.
     */
    public Shader_Delegate getShader() {
        return mShader;
    }

    /**
     * Returns the {@link MaskFilter} delegate or null if none have been set
     *
     * @return the delegate or null.
     */
    public MaskFilter_Delegate getMaskFilter() {
        return mMaskFilter;
    }

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

    @LayoutlibDelegate
    /*package*/ static int nGetFlags(long nativePaint) {
        // get the delegate from the native int.
        Paint_Delegate delegate = sManager.getDelegate(nativePaint);
        if (delegate == null) {
            return 0;
        }

        return delegate.mFlags;
    }



    @LayoutlibDelegate
    /*package*/ static void nSetFlags(long nativePaint, int flags) {
        // get the delegate from the native int.
        Paint_Delegate delegate = sManager.getDelegate(nativePaint);
        if (delegate == null) {
            return;
        }

        delegate.mFlags = flags;
    }

    @LayoutlibDelegate
    /*package*/ static void nSetFilterBitmap(long nativePaint, boolean filter) {
        setFlag(nativePaint, Paint.FILTER_BITMAP_FLAG, filter);
    }

    @LayoutlibDelegate
    /*package*/ static int nGetHinting(long nativePaint) {
        // get the delegate from the native int.
        Paint_Delegate delegate = sManager.getDelegate(nativePaint);
        if (delegate == null) {
            return Paint.HINTING_ON;
        }

        return delegate.mHintingMode;
    }

    @LayoutlibDelegate
    /*package*/ static void nSetHinting(long nativePaint, int mode) {
        // get the delegate from the native int.
        Paint_Delegate delegate = sManager.getDelegate(nativePaint);
        if (delegate == null) {
            return;
        }

        delegate.mHintingMode = mode;
    }

    @LayoutlibDelegate
    /*package*/ static void nSetAntiAlias(long nativePaint, boolean aa) {
        setFlag(nativePaint, Paint.ANTI_ALIAS_FLAG, aa);
    }

    @LayoutlibDelegate
    /*package*/ static void nSetSubpixelText(long nativePaint,
            boolean subpixelText) {
        setFlag(nativePaint, Paint.SUBPIXEL_TEXT_FLAG, subpixelText);
    }

    @LayoutlibDelegate
    /*package*/ static void nSetUnderlineText(long nativePaint,
            boolean underlineText) {
        setFlag(nativePaint, Paint.UNDERLINE_TEXT_FLAG, underlineText);
    }

    @LayoutlibDelegate
    /*package*/ static void nSetStrikeThruText(long nativePaint,
            boolean strikeThruText) {
        setFlag(nativePaint, Paint.STRIKE_THRU_TEXT_FLAG, strikeThruText);
    }

    @LayoutlibDelegate
    /*package*/ static void nSetFakeBoldText(long nativePaint,
            boolean fakeBoldText) {
        setFlag(nativePaint, Paint.FAKE_BOLD_TEXT_FLAG, fakeBoldText);
    }

    @LayoutlibDelegate
    /*package*/ static void nSetDither(long nativePaint, boolean dither) {
        setFlag(nativePaint, Paint.DITHER_FLAG, dither);
    }

    @LayoutlibDelegate
    /*package*/ static void nSetLinearText(long nativePaint, boolean linearText) {
        setFlag(nativePaint, Paint.LINEAR_TEXT_FLAG, linearText);
    }

    @LayoutlibDelegate
    /*package*/ static void nSetColor(long paintPtr, long colorSpaceHandle, long color) {
        Paint_Delegate delegate = sManager.getDelegate(paintPtr);
        if (delegate == null) {
            return;
        }

        delegate.mColor = Color.toArgb(color);
    }

    @LayoutlibDelegate
    /*package*/ static void nSetColor(long paintPtr, int color) {
        Paint_Delegate delegate = sManager.getDelegate(paintPtr);
        if (delegate == null) {
            return;
        }

        delegate.mColor = color;
    }

    @LayoutlibDelegate
    /*package*/ static void nSetAlpha(long nativePaint, int a) {
        // get the delegate from the native int.
        Paint_Delegate delegate = sManager.getDelegate(nativePaint);
        if (delegate == null) {
            return;
        }

        delegate.setAlpha(a);
    }

    @LayoutlibDelegate
    /*package*/ static float nGetStrokeWidth(long nativePaint) {
        // get the delegate from the native int.
        Paint_Delegate delegate = sManager.getDelegate(nativePaint);
        if (delegate == null) {
            return 1.f;
        }

        return delegate.mStrokeWidth;
    }

    @LayoutlibDelegate
    /*package*/ static void nSetStrokeWidth(long nativePaint, float width) {
        // get the delegate from the native int.
        Paint_Delegate delegate = sManager.getDelegate(nativePaint);
        if (delegate == null) {
            return;
        }

        delegate.mStrokeWidth = width;
    }

    @LayoutlibDelegate
    /*package*/ static float nGetStrokeMiter(long nativePaint) {
        // get the delegate from the native int.
        Paint_Delegate delegate = sManager.getDelegate(nativePaint);
        if (delegate == null) {
            return 1.f;
        }

        return delegate.mStrokeMiter;
    }

    @LayoutlibDelegate
    /*package*/ static void nSetStrokeMiter(long nativePaint, float miter) {
        // get the delegate from the native int.
        Paint_Delegate delegate = sManager.getDelegate(nativePaint);
        if (delegate == null) {
            return;
        }

        delegate.mStrokeMiter = miter;
    }

    @LayoutlibDelegate
    /*package*/ static void nSetShadowLayer(long paintPtr,
            float radius, float dx, float dy, long colorSpaceHandle,
            long shadowColor) {
        Bridge.getLog().fidelityWarning(LayoutLog.TAG_UNSUPPORTED,
                "Paint.setShadowLayer is not supported.", null, null, null /*data*/);
    }

    @LayoutlibDelegate
    /*package*/ static boolean nHasShadowLayer(long paint) {
        // FIXME
        Bridge.getLog().fidelityWarning(LayoutLog.TAG_UNSUPPORTED,
                "Paint.hasShadowLayer is not supported.", null, null, null /*data*/);
        return false;
    }

    @LayoutlibDelegate
    /*package*/ static boolean nIsElegantTextHeight(long nativePaint) {
        // get the delegate from the native int.
        Paint_Delegate delegate = sManager.getDelegate(nativePaint);
        return delegate != null && delegate.mFontVariant == FontVariant.ELEGANT;
    }

    @LayoutlibDelegate
    /*package*/ static void nSetElegantTextHeight(long nativePaint,
            boolean elegant) {
        // get the delegate from the native int.
        Paint_Delegate delegate = sManager.getDelegate(nativePaint);
        if (delegate == null) {
            return;
        }

        delegate.mFontVariant = elegant ? FontVariant.ELEGANT : FontVariant.COMPACT;
    }

    @LayoutlibDelegate
    /*package*/ static float nGetTextSize(long nativePaint) {
        // get the delegate from the native int.
        Paint_Delegate delegate = sManager.getDelegate(nativePaint);
        if (delegate == null) {
            return 1.f;
        }

        return delegate.mTextSize;
    }

    @LayoutlibDelegate
    /*package*/ static void nSetTextSize(long nativePaint, float textSize) {
        // get the delegate from the native int.
        Paint_Delegate delegate = sManager.getDelegate(nativePaint);
        if (delegate == null) {
            return;
        }

        if (delegate.mTextSize != textSize) {
            delegate.mTextSize = textSize;
            delegate.invalidateFonts();
        }
    }

    @LayoutlibDelegate
    /*package*/ static float nGetTextScaleX(long nativePaint) {
        // get the delegate from the native int.
        Paint_Delegate delegate = sManager.getDelegate(nativePaint);
        if (delegate == null) {
            return 1.f;
        }

        return delegate.mTextScaleX;
    }

    @LayoutlibDelegate
    /*package*/ static void nSetTextScaleX(long nativePaint, float scaleX) {
        // get the delegate from the native int.
        Paint_Delegate delegate = sManager.getDelegate(nativePaint);
        if (delegate == null) {
            return;
        }

        if (delegate.mTextScaleX != scaleX) {
            delegate.mTextScaleX = scaleX;
            delegate.invalidateFonts();
        }
    }

    @LayoutlibDelegate
    /*package*/ static float nGetTextSkewX(long nativePaint) {
        // get the delegate from the native int.
        Paint_Delegate delegate = sManager.getDelegate(nativePaint);
        if (delegate == null) {
            return 1.f;
        }

        return delegate.mTextSkewX;
    }

    @LayoutlibDelegate
    /*package*/ static void nSetTextSkewX(long nativePaint, float skewX) {
        // get the delegate from the native int.
        Paint_Delegate delegate = sManager.getDelegate(nativePaint);
        if (delegate == null) {
            return;
        }

        if (delegate.mTextSkewX != skewX) {
            delegate.mTextSkewX = skewX;
            delegate.invalidateFonts();
        }
    }

    @LayoutlibDelegate
    /*package*/ static float nAscent(long nativePaint) {
        // get the delegate
        Paint_Delegate delegate = sManager.getDelegate(nativePaint);
        if (delegate == null) {
            return 0;
        }

        List<FontInfo> fonts = delegate.getFonts();
        if (fonts.size() > 0) {
            java.awt.FontMetrics javaMetrics = fonts.get(0).mMetrics;
            // Android expects negative ascent so we invert the value from Java.
            return - javaMetrics.getAscent();
        }

        return 0;
    }

    @LayoutlibDelegate
    /*package*/ static float nDescent(long nativePaint) {
        // get the delegate
        Paint_Delegate delegate = sManager.getDelegate(nativePaint);
        if (delegate == null) {
            return 0;
        }

        List<FontInfo> fonts = delegate.getFonts();
        if (fonts.size() > 0) {
            java.awt.FontMetrics javaMetrics = fonts.get(0).mMetrics;
            return javaMetrics.getDescent();
        }

        return 0;

    }

    @LayoutlibDelegate
    /*package*/ static float nGetFontMetrics(long nativePaint,
            FontMetrics metrics) {
        // get the delegate
        Paint_Delegate delegate = sManager.getDelegate(nativePaint);
        if (delegate == null) {
            return 0;
        }

        return delegate.getFontMetrics(metrics);
    }

    @LayoutlibDelegate
    /*package*/ static int nGetFontMetricsInt(long nativePaint, FontMetricsInt fmi) {
        // get the delegate
        Paint_Delegate delegate = sManager.getDelegate(nativePaint);
        if (delegate == null) {
            return 0;
        }

        List<FontInfo> fonts = delegate.getFonts();
        if (fonts.size() > 0) {
            java.awt.FontMetrics javaMetrics = fonts.get(0).mMetrics;
            if (fmi != null) {
                // Android expects negative ascent so we invert the value from Java.
                fmi.top = (int)(- javaMetrics.getMaxAscent() * 1.15);
                fmi.ascent = - javaMetrics.getAscent();
                fmi.descent = javaMetrics.getDescent();
                fmi.bottom = (int)(javaMetrics.getMaxDescent() * 1.15);
                fmi.leading = javaMetrics.getLeading();
            }

            return javaMetrics.getHeight();
        }

        return 0;
    }

    @LayoutlibDelegate
    /*package*/ static int nBreakText(long nativePaint, char[] text,
            int index, int count, float maxWidth, int bidiFlags, float[] measuredWidth) {

        // get the delegate
        Paint_Delegate delegate = sManager.getDelegate(nativePaint);
        if (delegate == null) {
            return 0;
        }

        int inc = count > 0 ? 1 : -1;

        int measureIndex = 0;
        for (int i = index; i != index + count; i += inc, measureIndex++) {
            int start, end;
            if (i < index) {
                start = i;
                end = index;
            } else {
                start = index;
                end = i;
            }

            // measure from start to end
            RectF bounds = delegate.measureText(text, start, end - start + 1, null, 0, bidiFlags);
            float res = bounds.right - bounds.left;

            if (measuredWidth != null) {
                measuredWidth[measureIndex] = res;
            }

            if (res > maxWidth) {
                // we should not return this char index, but since it's 0-based
                // and we need to return a count, we simply return measureIndex;
                return measureIndex;
            }

        }

        return measureIndex;
    }

    @LayoutlibDelegate
    /*package*/ static int nBreakText(long nativePaint, String text, boolean measureForwards,
            float maxWidth, int bidiFlags, float[] measuredWidth) {
        return nBreakText(nativePaint, text.toCharArray(), 0, text.length(),
                maxWidth, bidiFlags, measuredWidth);
    }

    @LayoutlibDelegate
    /*package*/ static long nInit() {
        Paint_Delegate newDelegate = new Paint_Delegate();
        return sManager.addNewDelegate(newDelegate);
    }

    @LayoutlibDelegate
    /*package*/ static long nInitWithPaint(long paint) {
        // get the delegate from the native int.
        Paint_Delegate delegate = sManager.getDelegate(paint);
        if (delegate == null) {
            return 0;
        }

        Paint_Delegate newDelegate = new Paint_Delegate(delegate);
        return sManager.addNewDelegate(newDelegate);
    }

    @LayoutlibDelegate
    /*package*/ static void nReset(long native_object) {
        // get the delegate from the native int.
        Paint_Delegate delegate = sManager.getDelegate(native_object);
        if (delegate == null) {
            return;
        }

        delegate.reset();
    }

    @LayoutlibDelegate
    /*package*/ static void nSet(long native_dst, long native_src) {
        // get the delegate from the native int.
        Paint_Delegate delegate_dst = sManager.getDelegate(native_dst);
        if (delegate_dst == null) {
            return;
        }

        // get the delegate from the native int.
        Paint_Delegate delegate_src = sManager.getDelegate(native_src);
        if (delegate_src == null) {
            return;
        }

        delegate_dst.set(delegate_src);
    }

    @LayoutlibDelegate
    /*package*/ static int nGetStyle(long native_object) {
        // get the delegate from the native int.
        Paint_Delegate delegate = sManager.getDelegate(native_object);
        if (delegate == null) {
            return 0;
        }

        return delegate.mStyle;
    }

    @LayoutlibDelegate
    /*package*/ static void nSetStyle(long native_object, int style) {
        // get the delegate from the native int.
        Paint_Delegate delegate = sManager.getDelegate(native_object);
        if (delegate == null) {
            return;
        }

        delegate.mStyle = style;
    }

    @LayoutlibDelegate
    /*package*/ static int nGetStrokeCap(long native_object) {
        // get the delegate from the native int.
        Paint_Delegate delegate = sManager.getDelegate(native_object);
        if (delegate == null) {
            return 0;
        }

        return delegate.mCap;
    }

    @LayoutlibDelegate
    /*package*/ static void nSetStrokeCap(long native_object, int cap) {
        // get the delegate from the native int.
        Paint_Delegate delegate = sManager.getDelegate(native_object);
        if (delegate == null) {
            return;
        }

        delegate.mCap = cap;
    }

    @LayoutlibDelegate
    /*package*/ static int nGetStrokeJoin(long native_object) {
        // get the delegate from the native int.
        Paint_Delegate delegate = sManager.getDelegate(native_object);
        if (delegate == null) {
            return 0;
        }

        return delegate.mJoin;
    }

    @LayoutlibDelegate
    /*package*/ static void nSetStrokeJoin(long native_object, int join) {
        // get the delegate from the native int.
        Paint_Delegate delegate = sManager.getDelegate(native_object);
        if (delegate == null) {
            return;
        }

        delegate.mJoin = join;
    }

    @LayoutlibDelegate
    /*package*/ static boolean nGetFillPath(long native_object, long src, long dst) {
        Paint_Delegate paint = sManager.getDelegate(native_object);
        if (paint == null) {
            return false;
        }

        Path_Delegate srcPath = Path_Delegate.getDelegate(src);
        if (srcPath == null) {
            return true;
        }

        Path_Delegate dstPath = Path_Delegate.getDelegate(dst);
        if (dstPath == null) {
            return true;
        }

        Stroke stroke = paint.getJavaStroke();
        Shape strokeShape = stroke.createStrokedShape(srcPath.getJavaShape());

        dstPath.setJavaShape(strokeShape);

        // FIXME figure out the return value?
        return true;
    }

    @LayoutlibDelegate
    /*package*/ static long nSetShader(long native_object, long shader) {
        // get the delegate from the native int.
        Paint_Delegate delegate = sManager.getDelegate(native_object);
        if (delegate == null) {
            return shader;
        }

        delegate.mShader = Shader_Delegate.getDelegate(shader);

        return shader;
    }

    @LayoutlibDelegate
    /*package*/ static long nSetColorFilter(long native_object, long filter) {
        // get the delegate from the native int.
        Paint_Delegate delegate = sManager.getDelegate(native_object);
        if (delegate == null) {
            return filter;
        }

        delegate.mColorFilter = ColorFilter_Delegate.getDelegate(filter);

        // Log warning if it's not supported.
        if (delegate.mColorFilter != null && !delegate.mColorFilter.isSupported()) {
            Bridge.getLog().fidelityWarning(LayoutLog.TAG_COLORFILTER,
                    delegate.mColorFilter.getSupportMessage(), null, null, null /*data*/);
        }

        return filter;
    }

    @LayoutlibDelegate
    /*package*/ static void nSetXfermode(long native_object, int xfermode) {
        Paint_Delegate delegate = sManager.getDelegate(native_object);
        if (delegate == null) {
            return;
        }
        delegate.mPorterDuffMode = xfermode;
    }

    @LayoutlibDelegate
    /*package*/ static long nSetPathEffect(long native_object, long effect) {
        // get the delegate from the native int.
        Paint_Delegate delegate = sManager.getDelegate(native_object);
        if (delegate == null) {
            return effect;
        }

        delegate.mPathEffect = PathEffect_Delegate.getDelegate(effect);

        return effect;
    }

    @LayoutlibDelegate
    /*package*/ static long nSetMaskFilter(long native_object, long maskfilter) {
        // get the delegate from the native int.
        Paint_Delegate delegate = sManager.getDelegate(native_object);
        if (delegate == null) {
            return maskfilter;
        }

        delegate.mMaskFilter = MaskFilter_Delegate.getDelegate(maskfilter);

        // since none of those are supported, display a fidelity warning right away
        if (delegate.mMaskFilter != null && !delegate.mMaskFilter.isSupported()) {
            Bridge.getLog().fidelityWarning(LayoutLog.TAG_MASKFILTER,
                    delegate.mMaskFilter.getSupportMessage(), null, null, null /*data*/);
        }

        return maskfilter;
    }

    @LayoutlibDelegate
    /*package*/ static void nSetTypeface(long native_object, long typeface) {
        // get the delegate from the native int.
        Paint_Delegate delegate = sManager.getDelegate(native_object);
        if (delegate == null) {
            return;
        }

        Typeface_Delegate typefaceDelegate = Typeface_Delegate.getDelegate(typeface);
        if (delegate.mTypeface != typefaceDelegate) {
            delegate.mTypeface = typefaceDelegate;
            delegate.invalidateFonts();
        }
    }

    @LayoutlibDelegate
    /*package*/ static int nGetTextAlign(long native_object) {
        // get the delegate from the native int.
        Paint_Delegate delegate = sManager.getDelegate(native_object);
        if (delegate == null) {
            return 0;
        }

        return delegate.mTextAlign;
    }

    @LayoutlibDelegate
    /*package*/ static void nSetTextAlign(long native_object, int align) {
        // get the delegate from the native int.
        Paint_Delegate delegate = sManager.getDelegate(native_object);
        if (delegate == null) {
            return;
        }

        delegate.mTextAlign = align;
    }

    @LayoutlibDelegate
    /*package*/ static int nSetTextLocales(long native_object, String locale) {
        // get the delegate from the native int.
        Paint_Delegate delegate = sManager.getDelegate(native_object);
        if (delegate == null) {
            return 0;
        }

        delegate.setTextLocale(locale);
        return 0;
    }

    @LayoutlibDelegate
    /*package*/ static void nSetTextLocalesByMinikinLocaleListId(long paintPtr,
            int mMinikinLangListId) {
        // FIXME
    }

    @LayoutlibDelegate
    /*package*/ static float nGetTextAdvances(long native_object, char[] text, int index,
            int count, int contextIndex, int contextCount,
            int bidiFlags, float[] advances, int advancesIndex) {

        if (advances != null)
            for (int i = advancesIndex; i< advancesIndex+count; i++)
                advances[i]=0;
        // get the delegate from the native int.
        Paint_Delegate delegate = sManager.getDelegate(native_object);
        if (delegate == null) {
            return 0.f;
        }

        RectF bounds = delegate.measureText(text, index, count, advances, advancesIndex, bidiFlags);
        return bounds.right - bounds.left;
    }

    @LayoutlibDelegate
    /*package*/ static float nGetTextAdvances(long native_object, String text, int start, int end,
            int contextStart, int contextEnd, int bidiFlags, float[] advances, int advancesIndex) {
        // FIXME: support contextStart and contextEnd
        int count = end - start;
        char[] buffer = TemporaryBuffer.obtain(count);
        TextUtils.getChars(text, start, end, buffer, 0);

        return nGetTextAdvances(native_object, buffer, 0, count,
                contextStart, contextEnd - contextStart, bidiFlags, advances, advancesIndex);
    }

    @LayoutlibDelegate
    /*package*/ static int nGetTextRunCursor(Paint paint, long native_object, char[] text,
            int contextStart, int contextLength, int flags, int offset, int cursorOpt) {
        // FIXME
        Bridge.getLog().fidelityWarning(LayoutLog.TAG_UNSUPPORTED,
                "Paint.getTextRunCursor is not supported.", null, null, null /*data*/);
        return 0;
    }

    @LayoutlibDelegate
    /*package*/ static int nGetTextRunCursor(Paint paint, long native_object, String text,
            int contextStart, int contextEnd, int flags, int offset, int cursorOpt) {
        // FIXME
        Bridge.getLog().fidelityWarning(LayoutLog.TAG_UNSUPPORTED,
                "Paint.getTextRunCursor is not supported.", null, null, null /*data*/);
        return 0;
    }

    @LayoutlibDelegate
    /*package*/ static void nGetTextPath(long native_object, int bidiFlags, char[] text,
            int index, int count, float x, float y, long path) {
        // FIXME
        Bridge.getLog().fidelityWarning(LayoutLog.TAG_UNSUPPORTED,
                "Paint.getTextPath is not supported.", null, null, null /*data*/);
    }

    @LayoutlibDelegate
    /*package*/ static void nGetTextPath(long native_object, int bidiFlags, String text, int start,
            int end, float x, float y, long path) {
        // FIXME
        Bridge.getLog().fidelityWarning(LayoutLog.TAG_UNSUPPORTED,
                "Paint.getTextPath is not supported.", null, null, null /*data*/);
    }

    @LayoutlibDelegate
    /*package*/ static void nGetStringBounds(long nativePaint, String text, int start, int end,
            int bidiFlags, Rect bounds) {
        nGetCharArrayBounds(nativePaint, text.toCharArray(), start,
                end - start, bidiFlags, bounds);
    }

    @LayoutlibDelegate
    public static void nGetCharArrayBounds(long nativePaint, char[] text, int index,
            int count, int bidiFlags, Rect bounds) {

        // get the delegate from the native int.
        Paint_Delegate delegate = sManager.getDelegate(nativePaint);
        if (delegate == null) {
            return;
        }

        delegate.measureText(text, index, count, null, 0, bidiFlags).roundOut(bounds);
    }

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

    @LayoutlibDelegate
    /*package*/ static float nGetLetterSpacing(long nativePaint) {
        Paint_Delegate delegate = sManager.getDelegate(nativePaint);
        if (delegate == null) {
            return 0;
        }
        return delegate.mLetterSpacing;
    }

    @LayoutlibDelegate
    /*package*/ static void nSetLetterSpacing(long nativePaint, float letterSpacing) {
        Bridge.getLog().fidelityWarning(LayoutLog.TAG_TEXT_RENDERING,
                "Paint.setLetterSpacing() not supported.", null, null, null);
        Paint_Delegate delegate = sManager.getDelegate(nativePaint);
        if (delegate == null) {
            return;
        }
        delegate.mLetterSpacing = letterSpacing;
    }

    @LayoutlibDelegate
    /*package*/ static float nGetWordSpacing(long nativePaint) {
        Paint_Delegate delegate = sManager.getDelegate(nativePaint);
        if (delegate == null) {
            return 0;
        }
        return delegate.mWordSpacing;
    }

    @LayoutlibDelegate
    /*package*/ static void nSetWordSpacing(long nativePaint, float wordSpacing) {
        Paint_Delegate delegate = sManager.getDelegate(nativePaint);
        if (delegate == null) {
            return;
        }
        delegate.mWordSpacing = wordSpacing;
    }

    @LayoutlibDelegate
    /*package*/ static void nSetFontFeatureSettings(long nativePaint, String settings) {
        Bridge.getLog().fidelityWarning(LayoutLog.TAG_TEXT_RENDERING,
                "Paint.setFontFeatureSettings() not supported.", null, null, null);
    }

    @LayoutlibDelegate
    /*package*/ static int nGetStartHyphenEdit(long nativePaint) {
        Paint_Delegate delegate = sManager.getDelegate(nativePaint);
        if (delegate == null) {
            return 0;
        }
        return delegate.mStartHyphenEdit;
    }

    @LayoutlibDelegate
    /*package*/ static void nSetStartHyphenEdit(long nativePaint, int hyphen) {
        Paint_Delegate delegate = sManager.getDelegate(nativePaint);
        if (delegate == null) {
            return;
        }
        delegate.mStartHyphenEdit = hyphen;
    }

    @LayoutlibDelegate
    /*package*/ static int nGetEndHyphenEdit(long nativePaint) {
        Paint_Delegate delegate = sManager.getDelegate(nativePaint);
        if (delegate == null) {
            return 0;
        }
        return delegate.mEndHyphenEdit;
    }

    @LayoutlibDelegate
    /*package*/ static void nSetEndHyphenEdit(long nativePaint, int hyphen) {
        Paint_Delegate delegate = sManager.getDelegate(nativePaint);
        if (delegate == null) {
            return;
        }
        delegate.mEndHyphenEdit = hyphen;
    }

    @LayoutlibDelegate
    /*package*/ static boolean nHasGlyph(long nativePaint, int bidiFlags, String string) {
        Paint_Delegate delegate = sManager.getDelegate(nativePaint);
        if (delegate == null) {
            return false;
        }
        if (string.length() == 0) {
            return false;
        }
        if (string.length() > 1) {
            Bridge.getLog().fidelityWarning(LayoutLog.TAG_TEXT_RENDERING,
                    "Paint.hasGlyph() is not supported for ligatures.", null, null, null);
            return false;
        }

        char c = string.charAt(0);
        for (Font font : delegate.mTypeface.getFonts(delegate.mFontVariant)) {
            if (font.canDisplay(c)) {
                return true;
            }
        }
        return false;
    }


    @LayoutlibDelegate
    /*package*/ static float nGetRunAdvance(long nativePaint, @NonNull char[] text, int start,
            int end, int contextStart, int contextEnd,
            boolean isRtl, int offset) {
        int count = end - start;
        float[] advances = new float[count];
        int bidiFlags = isRtl ? Paint.BIDI_FORCE_RTL : Paint.BIDI_FORCE_LTR;
        nGetTextAdvances(nativePaint, text, start, count, contextStart,
                contextEnd - contextStart, bidiFlags, advances, 0);
        int startOffset = offset - start;  // offset from start.
        float sum = 0;
        for (int i = 0; i < startOffset; i++) {
            sum += advances[i];
        }
        return sum;
    }

    @LayoutlibDelegate
    /*package*/ static int nGetOffsetForAdvance(long nativePaint, char[] text, int start,
            int end, int contextStart, int contextEnd, boolean isRtl, float advance) {
        int count = end - start;
        float[] advances = new float[count];
        int bidiFlags = isRtl ? Paint.BIDI_FORCE_RTL : Paint.BIDI_FORCE_LTR;
        nGetTextAdvances(nativePaint, text, start, count, contextStart,
                contextEnd - contextStart, bidiFlags, advances, 0);
        float sum = 0;
        int i;
        for (i = 0; i < count && sum < advance; i++) {
            sum += advances[i];
        }
        float distanceToI = sum - advance;
        float distanceToIMinus1 = advance - (sum - advances[i]);
        return distanceToI > distanceToIMinus1 ? i : i - 1;
    }

    @LayoutlibDelegate
    /*package*/ static float nGetUnderlinePosition(long paintPtr) {
        return (1.0f / 9.0f) * nGetTextSize(paintPtr);
    }

    @LayoutlibDelegate
    /*package*/ static float nGetUnderlineThickness(long paintPtr) {
        return (1.0f / 18.0f) * nGetTextSize(paintPtr);
    }

    @LayoutlibDelegate
    /*package*/ static float nGetStrikeThruPosition(long paintPtr) {
        return (-79.0f / 252.0f) * nGetTextSize(paintPtr);
    }

    @LayoutlibDelegate
    /*package*/ static float nGetStrikeThruThickness(long paintPtr) {
        return (1.0f / 18.0f) * nGetTextSize(paintPtr);
    }

    @LayoutlibDelegate
    /*package*/ static boolean nEqualsForTextMeasurement(long leftPaintPtr, long rightPaintPtr) {
        return leftPaintPtr == rightPaintPtr;
    }

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

    /*package*/ Paint_Delegate() {
        reset();
    }

    private Paint_Delegate(Paint_Delegate paint) {
        set(paint);
    }

    private void set(Paint_Delegate paint) {
        mFlags = paint.mFlags;
        mColor = paint.mColor;
        mStyle = paint.mStyle;
        mCap = paint.mCap;
        mJoin = paint.mJoin;
        mTextAlign = paint.mTextAlign;

        if (mTypeface != paint.mTypeface) {
            mTypeface = paint.mTypeface;
            invalidateFonts();
        }

        if (mTextSize != paint.mTextSize) {
            mTextSize = paint.mTextSize;
            invalidateFonts();
        }

        if (mTextScaleX != paint.mTextScaleX) {
            mTextScaleX = paint.mTextScaleX;
            invalidateFonts();
        }

        if (mTextSkewX != paint.mTextSkewX) {
            mTextSkewX = paint.mTextSkewX;
            invalidateFonts();
        }

        mStrokeWidth = paint.mStrokeWidth;
        mStrokeMiter = paint.mStrokeMiter;
        mPorterDuffMode = paint.mPorterDuffMode;
        mColorFilter = paint.mColorFilter;
        mShader = paint.mShader;
        mPathEffect = paint.mPathEffect;
        mMaskFilter = paint.mMaskFilter;
        mHintingMode = paint.mHintingMode;
    }

    private void reset() {
        Typeface_Delegate defaultTypeface =
                Typeface_Delegate.getDelegate(Typeface.sDefaults[0].native_instance);

        mFlags = Paint.HIDDEN_DEFAULT_PAINT_FLAGS;
        mColor = 0xFF000000;
        mStyle = Paint.Style.FILL.nativeInt;
        mCap = Paint.Cap.BUTT.nativeInt;
        mJoin = Paint.Join.MITER.nativeInt;
        mTextAlign = 0;

        if (mTypeface != defaultTypeface) {
            mTypeface = defaultTypeface;
            invalidateFonts();
        }

        mStrokeWidth = 1.f;
        mStrokeMiter = 4.f;

        if (mTextSize != DEFAULT_TEXT_SIZE) {
            mTextSize = DEFAULT_TEXT_SIZE;
            invalidateFonts();
        }

        if (mTextScaleX != DEFAULT_TEXT_SCALE_X) {
            mTextScaleX = DEFAULT_TEXT_SCALE_X;
            invalidateFonts();
        }

        if (mTextSkewX != DEFAULT_TEXT_SKEW_X) {
            mTextSkewX = DEFAULT_TEXT_SKEW_X;
            invalidateFonts();
        }

        mPorterDuffMode = Xfermode.DEFAULT;
        mColorFilter = null;
        mShader = null;
        mPathEffect = null;
        mMaskFilter = null;
        mHintingMode = Paint.HINTING_ON;
    }

    private void invalidateFonts() {
        mFonts = null;
    }

    @Nullable
    private static FontInfo getFontInfo(@Nullable Font font, float textSize,
            @Nullable AffineTransform transform) {
        if (font == null) {
            return null;
        }

        Font transformedFont = font.deriveFont(textSize);
        if (transform != null) {
            // TODO: support skew
            transformedFont = transformedFont.deriveFont(transform);
        }

        // The metrics here don't have anti-aliasing set.
        return new FontInfo(transformedFont,
                Toolkit.getDefaultToolkit().getFontMetrics(transformedFont));
    }

    /*package*/ RectF measureText(char[] text, int index, int count, float[] advances,
            int advancesIndex, int bidiFlags) {
        return new BidiRenderer(null, this, text)
                .renderText(index, index + count, bidiFlags, advances, advancesIndex, false);
    }

    /*package*/ RectF measureText(char[] text, int index, int count, float[] advances,
            int advancesIndex, boolean isRtl) {
        return new BidiRenderer(null, this, text)
                .renderText(index, index + count, isRtl, advances, advancesIndex, false);
    }

    private float getFontMetrics(FontMetrics metrics) {
        List<FontInfo> fonts = getFonts();
        if (fonts.size() > 0) {
            java.awt.FontMetrics javaMetrics = fonts.get(0).mMetrics;
            if (metrics != null) {
                // Android expects negative ascent so we invert the value from Java.
                metrics.top = - javaMetrics.getMaxAscent();
                metrics.ascent = - javaMetrics.getAscent();
                metrics.descent = javaMetrics.getDescent();
                metrics.bottom = javaMetrics.getMaxDescent();
                metrics.leading = javaMetrics.getLeading();
            }

            return javaMetrics.getHeight();
        }

        return 0;
    }

    private void setTextLocale(String locale) {
        mLocale = new Locale(locale);
    }

    private static void setFlag(long nativePaint, int flagMask, boolean flagValue) {
        // get the delegate from the native int.
        Paint_Delegate delegate = sManager.getDelegate(nativePaint);
        if (delegate == null) {
            return;
        }

        if (flagValue) {
            delegate.mFlags |= flagMask;
        } else {
            delegate.mFlags &= ~flagMask;
        }
    }
}
