gt:             mBgBounds.bottom = mBgBounds.top + bgHeight;
context: /*
   * Copyright (c) 2016 Tim Malseed
   *
   *  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.simplecityapps.recyclerview_fastscroll.views;
  
  import android.animation.ObjectAnimator;
  import android.annotation.TargetApi;
  import android.content.res.Resources;
  import android.graphics.Canvas;
  import android.graphics.Paint;
  import android.graphics.Path;
  import android.graphics.Rect;
  import android.graphics.RectF;
  import android.graphics.Typeface;
  import android.os.Build;
  import android.text.TextUtils;
  import android.util.Log;
  
  import com.simplecityapps.recyclerview_fastscroll.utils.Utils;
  
  public class FastScrollPopup {
  
      private FastScrollRecyclerView mRecyclerView;
  
      private Resources mRes;
  
      private int mBackgroundSize;
      private int mCornerRadius;
  
      private Path mBackgroundPath = new Path();
      private RectF mBackgroundRect = new RectF();
      private Paint mBackgroundPaint;
  
      private Rect mInvalidateRect = new Rect();
      private Rect mTmpRect = new Rect();
  
      // The absolute bounds of the fast scroller bg
      private Rect mBgBounds = new Rect();
  
      private String mSectionName;
  
      private Paint mTextPaint;
      private Rect mTextBounds = new Rect();
  
      private float mAlpha = 1;
  
      private ObjectAnimator mAlphaAnimator;
      private boolean mVisible;
      private FastScrollPopupAlphaAnimator mFastScrollPopupAlphaAnimator;
  
      public FastScrollPopup(Resources resources, FastScrollRecyclerView recyclerView) {
  
          if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
              mFastScrollPopupAlphaAnimator = new FastScrollPopupApi14AlphaAnimatorImp();
          } else  if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
              mFastScrollPopupAlphaAnimator = new FastScrollPopupPreApi14AlphaAnimatorImp();
          }
          mRes = resources;
  
          mRecyclerView = recyclerView;
  
          mBackgroundSize = Utils.toPixels(mRes, 88);
          mCornerRadius = mBackgroundSize / 2;
  
          mBackgroundPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
  
          mTextPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
          mTextPaint.setAlpha(0);
          mTextPaint.setTextSize(Utils.toPixels(mRes, 56));
      }
  
      public void setBgColor(int color) {
          mBackgroundPaint.setColor(color);
          mRecyclerView.invalidate(mBgBounds);
      }
  
      public void setTextColor(int color) {
          mTextPaint.setColor(color);
          mRecyclerView.invalidate(mBgBounds);
      }
  
      /**
       * Animates the visibility of the fast scroller popup.
       */
      public void animateVisibility(boolean visible) {
          if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
              animateVisibility_HC(visible);
              return;
          }
          if (mVisible != visible) {
              mVisible = visible;
              setAlpha(visible ? 1 : 0);
          }
      }
  
      @TargetApi(Build.VERSION_CODES.HONEYCOMB)
      private void animateVisibility_HC(boolean visible) {
          if (mVisible != visible) {
              mVisible = visible;
              if (mAlphaAnimator != null) {
                  mAlphaAnimator.cancel();
              }
              mAlphaAnimator = mFastScrollPopupAlphaAnimator.getAlphaAnimator(this, visible ? 1f : 0f);
              mAlphaAnimator.setDuration(visible ? 200 : 150);
              mAlphaAnimator.start();
          }
      }
  
      // Setter/getter for the popup alpha for animations
      public void setAlpha(float alpha) {
          mAlpha = alpha;
          mRecyclerView.invalidate(mBgBounds);
      }
  
      public float getAlpha() {
          return mAlpha;
      }
  
      public void draw(Canvas canvas) {
          if (isVisible()) {
              // Draw the fast scroller popup
              int restoreCount = canvas.save(Canvas.MATRIX_SAVE_FLAG);
              canvas.translate(mBgBounds.left, mBgBounds.top);
              mTmpRect.set(mBgBounds);
              mTmpRect.offsetTo(0, 0);
  
              mBackgroundPath.reset();
              mBackgroundRect.set(mTmpRect);
  
              float[] radii;
  
              if (Utils.isRtl(mRes)) {
                  radii = new float[]{mCornerRadius, mCornerRadius, mCornerRadius, mCornerRadius, mCornerRadius, mCornerRadius, 0, 0};
              } else {
  
                  radii = new float[]{mCornerRadius, mCornerRadius, mCornerRadius, mCornerRadius, 0, 0, mCornerRadius, mCornerRadius};
              }
  
              mBackgroundPath.addRoundRect(mBackgroundRect, radii, Path.Direction.CW);
  
              mBackgroundPaint.setAlpha((int) (mAlpha * 255));
              mTextPaint.setAlpha((int) (mAlpha * 255));
              canvas.drawPath(mBackgroundPath, mBackgroundPaint);
              canvas.drawText(mSectionName, (mBgBounds.width() - mTextBounds.width()) / 2,
                      mBgBounds.height() - (mBgBounds.height() - mTextBounds.height()) / 2,
                      mTextPaint);
              canvas.restoreToCount(restoreCount);
          }
      }
  
      public void setSectionName(String sectionName) {
          if (!sectionName.equals(mSectionName)) {
              mSectionName = sectionName;
              mTextPaint.getTextBounds(sectionName, 0, sectionName.length(), mTextBounds);
              // Update the width to use measureText since that is more accurate
              mTextBounds.right = (int) (mTextBounds.left + mTextPaint.measureText(sectionName));
          }
      }
  
      public void setTypeface(Typeface typeface) {
          mTextPaint.setTypeface(typeface);
          mRecyclerView.invalidate(mBgBounds);
      }
  
      /**
       * Updates the bounds for the fast scroller.
       *
       * @return the invalidation rect for this update.
       */
      public Rect updateFastScrollerBounds(FastScrollRecyclerView recyclerView, int thumbOffsetY) {
          mInvalidateRect.set(mBgBounds);
  
          if (isVisible()) {
              // Calculate the dimensions and position of the fast scroller popup
              int edgePadding = recyclerView.getScrollBarWidth();
              int bgPadding = (mBackgroundSize - mTextBounds.height()) / 2;
              int bgHeight = mBackgroundSize;
              int bgWidth = Math.max(mBackgroundSize, mTextBounds.width() + (2 * bgPadding));
              if (Utils.isRtl(mRes)) {
                  mBgBounds.left = (2 * recyclerView.getScrollBarWidth());
                  mBgBounds.right = mBgBounds.left + bgWidth;
              } else {
                  mBgBounds.right = recyclerView.getWidth() - (2 * recyclerView.getScrollBarWidth());
                  mBgBounds.left = mBgBounds.right - bgWidth;
              }
              mBgBounds.top = thumbOffsetY - bgHeight + recyclerView.getScrollBarThumbHeight() / 2;
              mBgBounds.top = Math.max(edgePadding, Math.min(mBgBounds.top, recyclerView.getHeight() - edgePadding - bgHeight));
  