/*
 * Copyright (C) 2019 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 com.android.car.ui.drawable;

import android.content.res.Resources;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.ColorFilter;
import android.graphics.Paint;
import android.graphics.PixelFormat;
import android.graphics.Rect;
import android.graphics.Typeface;
import android.graphics.drawable.Drawable;
import android.text.TextPaint;
import android.util.AttributeSet;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;

import com.android.car.ui.R;

import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;

import java.io.IOException;

/**
 * A drawable to renders a given text. It can be used as part of a compound
 * drawable as follows:
 *
 * <pre>
 * {@code
 * <layer-list xmlns:android="http://schemas.android.com/apk/res/android">
 *     ...
 *     <item
 *         <drawable
 *             class="com.android.car.ui.drawable.CarUiTextDrawable"
 *             app:text="Some text"
 *             app:textSize="30sp">
 *         </drawable>
 *     </item>
 *     ...
 * </layer-list>
 * }
 * </pre>
 *
 * <b>Important: This class is referenced by reflection from overlays. DO NOT
 * RENAME, REMOVE OR MOVE TO ANOTHER PACKAGE, otherwise the overlays would
 * cause the target application to crash.</b>
 */
public class CarUiTextDrawable extends Drawable {
    private TextPaint mPaint = new TextPaint();
    private Rect mTextBounds = new Rect(); // Minimum bounds of the text only.

    // Attributes initialized during inflation
    private @Nullable String mText;
    private Typeface mTypeface = Typeface.DEFAULT;
    private float mTextSize = 10;
    private int mTextColor = Color.WHITE;

    /** Text sample used to measure font height */
    private static final String TEXT_HEIGHT_SAMPLE = "Ag";

    /** Constructor available to include this drawable by code */
    public CarUiTextDrawable(@Nullable String text,
                             Typeface typeface,
                             float textSize,
                             int textColor) {
        mText = text;
        mTypeface = typeface;
        mTextSize = textSize;
        mTextColor = textColor;
        refreshTextBoundsAndInvalidate();
    }

    /** Constructor invoked by XML inflator */
    public CarUiTextDrawable() {
        // To be used during inflation.
    }

    /** Updates the text rendered by this drawable */
    public void setText(@Nullable String text) {
        this.mText = text;
        refreshTextBoundsAndInvalidate();
    }

    @Override
    public int getIntrinsicHeight() {
        return mTextBounds.height();
    }

    @Override
    public int getIntrinsicWidth() {
        return mTextBounds.width();
    }

    @Override
    public void draw(Canvas canvas) {
        Rect bounds = getBounds();
        if (bounds.isEmpty() || mPaint.getAlpha() == 0) {
            return;
        }

        // Draw text.
        if (mText != null) {
            canvas.drawText(mText,
                    bounds.centerX(),
                    bounds.centerY() + (mTextBounds.height() / 2.0f),
                    mPaint);
        }
    }

    @Override
    public void setAlpha(int alpha) {
        final int old = mPaint.getAlpha();
        if (alpha != old) {
            mPaint.setAlpha(alpha);
            invalidateSelf();
        }
    }

    @Override
    public void setColorFilter(ColorFilter cf) {
        mPaint.setColorFilter(cf);
        invalidateSelf();
    }

    @Override
    public int getOpacity() {
        return mPaint.bgColor != 0 ? PixelFormat.OPAQUE : PixelFormat.TRANSPARENT;
    }

    /**
     * Call this to re-measure the text when properties that may affect the
     * textBounds are changed.
     */
    private void refreshTextBoundsAndInvalidate() {
        mPaint.setTypeface(mTypeface);
        mPaint.setTextSize(mTextSize);
        mPaint.setColor(mTextColor);
        mPaint.setTextAlign(Paint.Align.CENTER);
        mPaint.setAntiAlias(true);
        mPaint.setDither(true);
        calculateTextBounds(mPaint, mText, mTextBounds);
        invalidateSelf();
    }

    /**
     * Calculate the bounds of the given text.
     *
     * The textBounds are different from the drawable bounds: the textBounds is
     * is strictly a subset, and measures the minimum bounding box necessary to
     * draw the text. The left and right of the textBounds are used to calculate
     * the intrinsic width and intrinsic height.
     *
     * Text height is calculated based on a fixed sample text (to avoid height
     * changing every time a different text is rendered)
     */
    private void calculateTextBounds(TextPaint paint, @Nullable String text, Rect outBounds) {
        outBounds.setEmpty();
        paint.getTextBounds(TEXT_HEIGHT_SAMPLE, 0, TEXT_HEIGHT_SAMPLE.length(), outBounds);

        if (text != null) {
            // Save the top and bottom bounds of the sample text.
            int top = outBounds.top;
            int bottom = outBounds.bottom;

            // Get the actual text bounds.
            paint.getTextBounds(text, 0, text.length(), outBounds);

            // Replace top and bottom with sample text bounds. We only care about left
            // and right.
            outBounds.top = top;
            outBounds.bottom = bottom;
        } else {
            outBounds.left = 0;
            outBounds.right = 0;
        }
    }

    private @NonNull TypedArray themedObtainAttributes(@NonNull Resources res,
                                                          @Nullable Resources.Theme theme,
                                                          @NonNull AttributeSet set,
                                                          @NonNull int[] attrs) {
        if (theme == null) {
            return res.obtainAttributes(set, attrs);
        }
        return theme.obtainStyledAttributes(set, attrs, 0, 0);
    }

    @Override
    public void inflate(@NonNull Resources r, @NonNull XmlPullParser parser,
                        @NonNull AttributeSet attrs, @Nullable Resources.Theme theme)
            throws XmlPullParserException, IOException {
        final TypedArray a = themedObtainAttributes(r, theme, attrs, R.styleable.CarUiTextDrawable);
        mText = a.getString(R.styleable.CarUiTextDrawable_text);
        mTypeface = Typeface.create(a.getString(R.styleable.CarUiTextDrawable_typeface),
                Typeface.NORMAL);
        mTextSize = a.getDimension(R.styleable.CarUiTextDrawable_textSize, 10);
        mTextColor = a.getColor(R.styleable.CarUiTextDrawable_textColor,
                r.getColor(R.color.car_ui_primary_text_color, theme));
        a.recycle();
        refreshTextBoundsAndInvalidate();
        super.inflate(r, parser, attrs, theme);
    }
}
