/*
 * 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 com.android.launcher2;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Bitmap.Config;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.PorterDuff.Mode;
import android.graphics.drawable.Drawable;
import android.text.Layout;
import android.util.AttributeSet;
import android.widget.TextView;

/*
 * This class is a bit of a hack, designed to speed up long text labels in Launcher. It caches the
 * text in a TextView to a bitmap and then just draws that Bitmap instead afterward, speeding up
 * rendering. Marquee scrolling is not currently supported.
 *
 */
public class CachedTextView extends TextView {
    private Bitmap mCache;
    private final Paint mCachePaint = new Paint();
    private final Canvas mCacheCanvas = new Canvas();

    private int mPrevAlpha = -1;
    private boolean mIsBuildingCache;
    boolean mIsTextCacheDirty;
    float mTextCacheLeft;
    float mTextCacheTop;
    float mTextCacheScrollX;
    float mRectLeft, mRectTop;
    private float mPaddingH = 0;
    private float mPaddingV = 0;
    private CharSequence mText;
    private boolean mEnabled = true;

    public CachedTextView(Context context) {
        super(context);
    }

    public CachedTextView(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public CachedTextView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
    }

    protected int getCacheTopPadding() {
        return 0;
    }
    protected int getCacheLeftPadding() {
        return 0;
    }
    protected int getCacheRightPadding() {
        return 0;
    }
    protected int getCacheBottomPadding() {
        return 0;
    }

    public void disableCache() {
        mEnabled = false;
    }

    public void setText(CharSequence text, BufferType type) {
        super.setText(text, type);
        mIsTextCacheDirty = true;
    }

    private void buildAndUpdateCache() {
        final Layout layout = getLayout();
        final int left = getCompoundPaddingLeft();
        final int top = getExtendedPaddingTop();
        final float prevAlpha = getAlpha();

        mTextCacheLeft = layout.getLineLeft(0) - getCacheLeftPadding();
        mTextCacheTop = top + layout.getLineTop(0) - mPaddingV - getCacheTopPadding();

        mRectLeft = mScrollX + getLeft();
        mRectTop = 0;
        mTextCacheScrollX = mScrollX;

        final float textCacheRight =
            Math.min(left + layout.getLineRight(0) + mPaddingH, mScrollX + mRight - mLeft) +
            getCacheRightPadding();
        final float textCacheBottom = top + layout.getLineBottom(0) + mPaddingV +
            getCacheBottomPadding();
        final float xCharWidth = getPaint().measureText("x");

        int width = (int) (textCacheRight - mTextCacheLeft + (2 * xCharWidth));
        int height = (int) (textCacheBottom - mTextCacheTop);

        if (width != 0 && height != 0) {
            if (mCache != null) {
                if (mCache.getWidth() != width || mCache.getHeight() != height) {
                    mCache.recycle();
                    mCache = null;
                }
            }
            if (mCache == null) {
                mCache = Bitmap.createBitmap(width, height, Config.ARGB_8888);
                mCacheCanvas.setBitmap(mCache);
            } else {
                mCacheCanvas.drawColor(0, Mode.CLEAR);
            }

            mCacheCanvas.save();
            mCacheCanvas.translate(-mTextCacheLeft, -mTextCacheTop);

            mIsBuildingCache = true;
            setAlpha(1.0f);
            draw(mCacheCanvas);
            setAlpha(prevAlpha);
            mIsBuildingCache = false;
            mCacheCanvas.restore();

            // A hack-- we set the text to be one space (we don't make it empty just to avoid any
            // potential issues with text measurement, like line height, etc.) so that the text view
            // doesn't draw it anymore, since it's been cached.
            mText = getText();
            setText(" ");
        }
    }

    public CharSequence getText() {
        return (mText == null) ? super.getText() : mText;
    }

    public void draw(Canvas canvas) {
        if (mEnabled && mIsTextCacheDirty && !mIsBuildingCache) {
            buildAndUpdateCache();
            mIsTextCacheDirty = false;
        }
        if (mCache != null && !mIsBuildingCache) {
            canvas.drawBitmap(mCache, mTextCacheLeft - mTextCacheScrollX + mScrollX,
                    mTextCacheTop, mCachePaint);
        }
        super.draw(canvas);
    }

    protected boolean isBuildingCache() {
        return mIsBuildingCache;
    }

    @Override
    protected boolean onSetAlpha(int alpha) {
        if (mPrevAlpha != alpha) {
            mPrevAlpha = alpha;
            mCachePaint.setAlpha(alpha);

            // We manually update the drawables alpha since the default TextView implementation may
            // not do this if there is a background set (which we may due to the focus bg)
            final Drawable[] dr = getCompoundDrawables();
            for (int i = 0; i < dr.length; ++i) {
                if (dr[i] != null) {
                    dr[i].mutate().setAlpha(alpha);
                }
            }

            super.onSetAlpha(alpha);
        }
        return true;
    }
}
