/*
 * Copyright (C) 2013 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 android.annotation.NonNull;
import android.annotation.Nullable;
import android.graphics.Paint_Delegate.FontInfo;
import android.icu.lang.UScriptRun;
import android.icu.text.Bidi;
import android.icu.text.BidiRun;

import java.awt.Font;
import java.awt.Graphics2D;
import java.awt.Toolkit;
import java.awt.font.FontRenderContext;
import java.awt.font.GlyphVector;
import java.awt.geom.AffineTransform;
import java.awt.geom.Rectangle2D;
import java.util.Arrays;
import java.util.LinkedList;
import java.util.List;

/**
 * Render the text by breaking it into various scripts and using the right font for each script.
 * Can be used to measure the text without actually drawing it.
 */
@SuppressWarnings("deprecation")
public class BidiRenderer {
    private static final String JETBRAINS_VENDOR_ID = "JetBrains s.r.o";
    private static final String JAVA_VENDOR = System.getProperty("java.vendor");
    /** When scaleX is bigger than this, we need to apply the workaround for http://b.android.com/211659 */
    private static final double SCALEX_WORKAROUND_LIMIT = 9;

    private static class ScriptRun {
        private final int start;
        private final int limit;
        private final Font font;

        private ScriptRun(int start, int limit, @NonNull Font font) {
            this.start = start;
            this.limit = limit;
            this.font = font;
        }
    }

    private final Graphics2D mGraphics;
    private final Paint_Delegate mPaint;
    private char[] mText;
    // Bounds of the text drawn so far.
    private RectF mBounds;
    private float mBaseline;
    private final Bidi mBidi = new Bidi();


    /**
     * @param graphics May be null.
     * @param paint The Paint to use to get the fonts. Should not be null.
     * @param text Unidirectional text. Should not be null.
     */
    public BidiRenderer(Graphics2D graphics, Paint_Delegate paint, char[] text) {
        assert (paint != null);
        mGraphics = graphics;
        mPaint = paint;
        mText = text;
        mBounds = new RectF();
    }

    /**
     *
     * @param x The x-coordinate of the left edge of where the text should be drawn on the given
     *            graphics.
     * @param y The y-coordinate at which to draw the text on the given mGraphics.
     *
     */
    public BidiRenderer setRenderLocation(float x, float y) {
        mBounds.set(x, y, x, y);
        mBaseline = y;
        return this;
    }

    /**
     * Perform Bidi Analysis on the text and then render it.
     * <p/>
     * To skip the analysis and render unidirectional text, see {@link
     * #renderText(int, int, boolean, float[], int, boolean)}
     */
    public RectF renderText(int start, int limit, int bidiFlags, float[] advances,
            int advancesIndex, boolean draw) {
        mBidi.setPara(Arrays.copyOfRange(mText, start, limit), (byte)getIcuFlags(bidiFlags), null);
        mText = mBidi.getText();
        for (int i = 0; i < mBidi.countRuns(); i++) {
            BidiRun visualRun = mBidi.getVisualRun(i);
            boolean isRtl = visualRun.getDirection() == Bidi.RTL;
            renderText(visualRun.getStart(), visualRun.getLimit(), isRtl, advances,
                    advancesIndex, draw);
        }
        return mBounds;
    }

    /**
     * Render unidirectional text.
     * <p/>
     * This method can also be used to measure the width of the text without actually drawing it.
     * <p/>
     * @param start index of the first character
     * @param limit index of the first character that should not be rendered.
     * @param isRtl is the text right-to-left
     * @param advances If not null, then advances for each character to be rendered are returned
     *            here.
     * @param advancesIndex index into advances from where the advances need to be filled.
     * @param draw If true and {@code graphics} is not null, draw the rendered text on the graphics
     *            at the given co-ordinates
     * @return A rectangle specifying the bounds of the text drawn.
     */
    public RectF renderText(int start, int limit, boolean isRtl, float[] advances,
            int advancesIndex, boolean draw) {
        // We break the text into scripts and then select font based on it and then render each of
        // the script runs.
        for (ScriptRun run : getScriptRuns(mText, start, limit, mPaint.getFonts())) {
            int flag = Font.LAYOUT_NO_LIMIT_CONTEXT | Font.LAYOUT_NO_START_CONTEXT;
            flag |= isRtl ? Font.LAYOUT_RIGHT_TO_LEFT : Font.LAYOUT_LEFT_TO_RIGHT;
            renderScript(run.start, run.limit, run.font, flag, advances, advancesIndex, draw);
            advancesIndex += run.limit - run.start;
        }
        return mBounds;
    }

    /**
     * Render a script run to the right of the bounds passed. Use the preferred font to render as
     * much as possible. This also implements a fallback mechanism to render characters that cannot
     * be drawn using the preferred font.
     */
    private void renderScript(int start, int limit, Font preferredFont, int flag,
            float[] advances, int advancesIndex, boolean draw) {
        if (mPaint.getFonts().size() == 0 || preferredFont == null) {
            return;
        }

        while (start < limit) {
            int canDisplayUpTo = preferredFont.canDisplayUpTo(mText, start, limit);
            if (canDisplayUpTo == -1) {
                // We can draw all characters in the text.
                render(start, limit, preferredFont, flag, advances, advancesIndex, draw);
                return;
            }
            if (canDisplayUpTo > start) {
                // We can draw something.
                render(start, canDisplayUpTo, preferredFont, flag, advances, advancesIndex, draw);
                advancesIndex += canDisplayUpTo - start;
                start = canDisplayUpTo;
            } else {
                // We can display everything with the preferred font. Search for the font that
                // allows us to display the maximum number of chars
                List<FontInfo> fontInfos = mPaint.getFonts();
                Font bestFont = null;
                int highestUpTo = canDisplayUpTo;
                //noinspection ForLoopReplaceableByForEach
                for (int i = 0; i < fontInfos.size(); i++) {
                    Font font = fontInfos.get(i).mFont;

                    if (preferredFont == font) {
                        // We know this font won't work since we've already tested it at the
                        // beginning of the loop
                        continue;
                    }

                    if (font == null) {
                        logFontWarning();
                        continue;
                    }

                    canDisplayUpTo = font.canDisplayUpTo(mText, start, limit);
                    if (canDisplayUpTo == -1) {
                        // This font can dis
                        highestUpTo = limit;
                        bestFont = font;
                        break;
                    } else if (canDisplayUpTo > highestUpTo) {
                        highestUpTo = canDisplayUpTo;
                        bestFont = font;
                        // Keep searching in case there is a font that allows to display even
                        // more text
                    }
                }

                if (bestFont != null) {
                    render(start, highestUpTo, bestFont, flag, advances, advancesIndex, draw);
                    advancesIndex += highestUpTo - start;
                    start = highestUpTo;
                } else {
                    int charCount = Character.isHighSurrogate(mText[start]) ? 2 : 1;

                    // No font can display this char. Use the preferred font and skip this char.
                    // The char will most probably appear as a box or a blank space. We could,
                    // probably, use some heuristics and break the character into the base
                    // character and diacritics and then draw it, but it's probably not worth the
                    // effort.
                    render(start, start + charCount, preferredFont, flag, advances, advancesIndex,
                            draw);
                    start += charCount;
                    advancesIndex += charCount;
                }
            }
        }
    }

    private static void logFontWarning() {
        Bridge.getLog().fidelityWarning(LayoutLog.TAG_BROKEN,
                "Some fonts could not be loaded. The rendering may not be perfect.", null, null);
    }

    /**
     * Renders the text to the right of the bounds with the given font.
     * @param font The font to render the text with.
     */
    private void render(int start, int limit, Font font, int flag, float[] advances,
            int advancesIndex, boolean draw) {
        FontRenderContext frc = mGraphics != null ? mGraphics.getFontRenderContext() :
                    Toolkit.getDefaultToolkit().getFontMetrics(font).getFontRenderContext();

        boolean frcIsAntialiased = frc.isAntiAliased();
        boolean useAntialiasing = mPaint.isAntiAliased();

        if (frcIsAntialiased) {
            if (!useAntialiasing) {
                // The context has antialiasing enabled but the paint does not. We need to
                // disable it
                frc = new FontRenderContext(font.getTransform(), false,
                        frc.usesFractionalMetrics());
            } else {
                // In this case both the paint and the context antialising match but we need
                // to check for a bug in the JDK
                // Workaround for http://b.android.com/211659 (disable antialiasing)
                if (font.isTransformed()) {
                    AffineTransform transform = font.getTransform();
                    if (transform.getScaleX() >= SCALEX_WORKAROUND_LIMIT &&
                            JETBRAINS_VENDOR_ID.equals(JAVA_VENDOR)) {
                        frc = new FontRenderContext(transform, false, frc.usesFractionalMetrics());
                    }
                }
            }
        } else if (useAntialiasing) {
            // The context does not have antialiasing enabled but the paint does. We need to
            // enable it unless we need to avoid the JDK bug

            AffineTransform transform = font.getTransform();
            // Workaround for http://b.android.com/211659 (disable antialiasing)
            if (transform.getScaleX() < SCALEX_WORKAROUND_LIMIT ||
                    !JETBRAINS_VENDOR_ID.equals(JAVA_VENDOR)) {
                frc = new FontRenderContext(font.getTransform(), true, frc.usesFractionalMetrics());
            }
        }

        GlyphVector gv = font.layoutGlyphVector(frc, mText, start, limit, flag);
        int ng = gv.getNumGlyphs();
        int[] ci = gv.getGlyphCharIndices(0, ng, null);
        if (advances != null) {
            for (int i = 0; i < ng; i++) {
                if (mText[ci[i]] == '\uFEFF') {
                    // Workaround for bug in JetBrains JDK
                    // where the character \uFEFF is associated a glyph with non-zero width
                    continue;
                }
                int adv_idx = advancesIndex + ci[i];
                advances[adv_idx] += gv.getGlyphMetrics(i).getAdvanceX();
            }
        }
        if (draw && mGraphics != null) {
            mGraphics.drawGlyphVector(gv, mBounds.right, mBaseline);
        }

        // Update the bounds.
        Rectangle2D awtBounds = gv.getLogicalBounds();
        // If the width of the bounds is zero, no text had been drawn earlier. Hence, use the
        // coordinates from the bounds as an offset.
        if (Math.abs(mBounds.right - mBounds.left) == 0) {
            mBounds = awtRectToAndroidRect(awtBounds, mBounds.right, mBaseline, mBounds);
        } else {
            mBounds.union(awtRectToAndroidRect(awtBounds, mBounds.right, mBaseline, null));
        }
    }

    // --- Static helper methods ---

    private static RectF awtRectToAndroidRect(Rectangle2D awtRec, float offsetX, float offsetY,
            @Nullable RectF destination) {
        float left = (float) awtRec.getX();
        float top = (float) awtRec.getY();
        float right = (float) (left + awtRec.getWidth());
        float bottom = (float) (top + awtRec.getHeight());
        if (destination != null) {
            destination.set(left, top, right, bottom);
        } else {
            destination = new RectF(left, top, right, bottom);
        }
        destination.offset(offsetX, offsetY);
        return destination;
    }

    private static List<ScriptRun> getScriptRuns(char[] text, int start, int limit, List<FontInfo> fonts) {
        LinkedList<ScriptRun> scriptRuns = new LinkedList<>();

        int count = limit - start;
        UScriptRun uScriptRun = new UScriptRun(text, start, count);
        while (uScriptRun.next()) {
            int scriptStart = uScriptRun.getScriptStart();
            int scriptLimit = uScriptRun.getScriptLimit();
            ScriptRun run = new ScriptRun(
                    scriptStart, scriptLimit,
                    getScriptFont(text, scriptStart, scriptLimit, fonts));
            scriptRuns.add(run);
        }
        return scriptRuns;
    }

    // TODO: Replace this method with one which returns the font based on the scriptCode.
    @NonNull
    private static Font getScriptFont(char[] text, int start, int limit, List<FontInfo> fonts) {
        if (fonts.isEmpty()) {
            logFontWarning();
            // Fallback font in case no font can be loaded
            return Font.getFont(Font.SERIF);
        }

        // From all the fonts, select the one that can display the highest number of characters
        Font bestFont = fonts.get(0).mFont;
        int bestFontCount = 0;
        for (FontInfo fontInfo : fonts) {
            int count = fontInfo.mFont.canDisplayUpTo(text, start, limit);
            if (count == -1) {
                // This font can display everything, return this one
                return fontInfo.mFont;
            }

            if (count > bestFontCount) {
                bestFontCount = count;
                bestFont = fontInfo.mFont;
            }
        }

        return bestFont;
    }

    private static int getIcuFlags(int bidiFlag) {
        switch (bidiFlag) {
            case Paint.BIDI_LTR:
            case Paint.BIDI_FORCE_LTR:
                return Bidi.DIRECTION_LEFT_TO_RIGHT;
            case Paint.BIDI_RTL:
            case Paint.BIDI_FORCE_RTL:
                return Bidi.DIRECTION_RIGHT_TO_LEFT;
            case Paint.BIDI_DEFAULT_LTR:
                return Bidi.DIRECTION_DEFAULT_LEFT_TO_RIGHT;
            case Paint.BIDI_DEFAULT_RTL:
                return Bidi.DIRECTION_DEFAULT_RIGHT_TO_LEFT;
            default:
                assert false;
                return Bidi.DIRECTION_DEFAULT_LEFT_TO_RIGHT;
        }
    }
}
