content: /*
   * Created by LuaView.
   * Copyright (c) 2017, Alibaba Group. All rights reserved.
   *
   * This source code is licensed under the MIT.
   * For the full copyright and license information,please view the LICENSE file in the root directory of this source tree.
   */
  
  package com.taobao.luaview.view.foreground;
  
  import android.annotation.TargetApi;
  import android.content.Context;
  import android.content.res.ColorStateList;
  import android.graphics.Canvas;
  import android.graphics.Rect;
  import android.graphics.drawable.Drawable;
  import android.graphics.drawable.RippleDrawable;
  import android.os.Build;
  import android.util.AttributeSet;
  import android.view.Gravity;
  import android.view.View;
  
  import com.taobao.android.luaview.R;
  
  /**
   * Delegate that actually does the foreground things, so that the logic can be shared between views
   * and so that others can easily create views that support a foreground
   */
  public class ForegroundDelegate {
  
      private Drawable mForeground;
  
      private final Rect mSelfBounds = new Rect();
  
      private final Rect mOverlayBounds = new Rect();
  
      private int mForegroundGravity = Gravity.FILL;
  
      protected boolean mForegroundInPadding = true;
  
      boolean mForegroundBoundsChanged = false;
  
      public ForegroundDelegate() {
      }
  
      public static void setupDefaultForeground(View view) {
          setupDefaultForeground(view, null, null);
      }
  
      public static void setupDefaultForeground(View view, Integer color, Integer alpha) {
          if (view instanceof IForeground && ((IForeground) view).hasForeground() == false && view.getResources() != null) {
              setupForeground(view, view.getResources().getDrawable(R.drawable.lv_click_foreground), color, alpha);
          }
      }
  
      private static void setupForeground(View view, Drawable drawable, Integer color, Integer alpha) {
          if (view instanceof IForeground) {
              if (color != null) {
                  if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {
                      if (drawable instanceof RippleDrawable) {
                          RippleDrawable rippleDrawable = (RippleDrawable) drawable;
                          rippleDrawable.setColor(ColorStateList.valueOf(color));
                          if (alpha != null) {
                              rippleDrawable.setAlpha(alpha);
                          }
  
                      }
                  }
              }
              ((IForeground) view).setForeground(drawable);
          }
      }
  
      public static void clearForeground(View view) {
          if (view instanceof IForeground) {
              ((IForeground) view).clearForeground();
          }
      }
  
      public void init(Context context) {
      }
  
      public void init(Context context, AttributeSet attrs, int defStyle, int defStyleRes) {
      }
  
      public void onLayout(boolean changed, int left, int top, int right, int bottom) {
          mForegroundBoundsChanged = true;
  //        mForegroundBoundsChanged = changed;
      }
  
      public void onSizeChanged(int w, int h, int oldw, int oldh) {
          mForegroundBoundsChanged = true;
      }
  
      /**
       * Returns the drawable used as the foreground of this FrameLayout. The
       * foreground drawable, if non-null, is always drawn on top of the children.
       *
       * @return A Drawable or null if no foreground was set.
       */
      public Drawable getForeground() {
          return mForeground;
      }
  
      /**
       * Supply a Drawable that is to be rendered on top of all of the child
       * views in the frame layout.  Any padding in the Drawable will be taken
       * into account by ensuring that the children are inset to be placed
       * inside of the padding area.
       *
       * @param drawable The Drawable to be drawn on top of the children.
       */
      public void setForeground(View view, Drawable drawable) {
          if (view != null) {
              if (mForeground != drawable) {
                  if (mForeground != null) {
                      mForeground.setCallback(null);
                      view.unscheduleDrawable(mForeground);
                  }
  
                  mForeground = drawable;
  
                  if (drawable != null) {
                      view.setWillNotDraw(false);
                      drawable.setCallback(view);
                      if (drawable.isStateful()) {
                          drawable.setState(view.getDrawableState());
                      }
                      if (mForegroundGravity == Gravity.FILL) {
                          Rect padding = new Rect();
                          drawable.getPadding(padding);
                      }
  
                      //update bounds
                      updateBounds(view, drawable);//added by song
                  } else {
                      view.setWillNotDraw(true);
                  }
                  view.requestLayout();
                  view.invalidate();
              }
          }
      }
  
      public int getForegroundGravity() {
          return mForegroundGravity;
      }
  
      public void setForegroundGravity(View view, int foregroundGravity) {
          if (view != null) {
              if (mForegroundGravity != foregroundGravity) {
                  if ((foregroundGravity & Gravity.RELATIVE_HORIZONTAL_GRAVITY_MASK) == 0) {
                      foregroundGravity |= Gravity.START;
                  }
  
                  if ((foregroundGravity & Gravity.VERTICAL_GRAVITY_MASK) == 0) {
                      foregroundGravity |= Gravity.TOP;
                  }
  
                  mForegroundGravity = foregroundGravity;
  
                  if (mForegroundGravity == Gravity.FILL && mForeground != null) {
                      Rect padding = new Rect();
                      mForeground.getPadding(padding);
                  }
  
                  view.requestLayout();
              }
          }
      }
  
      public void jumpDrawablesToCurrentState() {
          if (mForeground != null) mForeground.jumpToCurrentState();
      }
  
      public void drawableStateChanged(View view) {
          if (view != null) {
              if (mForeground != null && mForeground.isStateful()) {
                  mForeground.setState(view.getDrawableState());
              }
          }
      }
  
      public void draw(View view, Canvas canvas) {
          if (view != null) {
              if (mForeground != null) {
                  final Drawable foreground = mForeground;
  
                  if (mForegroundBoundsChanged) {
                      mForegroundBoundsChanged = false;
                      updateBounds(view, foreground);
                  }
  
                  foreground.draw(canvas);
              }
          }
      }
  
      public void updateBounds(View view) {
          updateBounds(view, mForeground);
      }
  
      /**
       * 更新bounds
       *
       * @param view
       * @param drawable
       */
      private void updateBounds(View view, Drawable drawable) {
          if (drawable != null) {
              final Rect selfBounds = mSelfBounds;
              final Rect overlayBounds = mOverlayBounds;
  
              final int w = view.getRight() - view.getLeft();
              final int h = view.getBottom() - view.getTop();
  
              if (mForegroundInPadding) {
                  selfBounds.set(0, 0, w, h);
              } else {
                  selfBounds.set(view.getPaddingLeft(), view.getPaddingTop(), w - view.getPaddingRight(), h - view.getPaddingBottom());
              }
  
              Gravity.apply(mForegroundGravity, drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight(), selfBounds, overlayBounds);
              drawable.setBounds(overlayBounds);
          }
      }
  
      @TargetApi(Build.VERSION_CODES.LOLLIPOP)
      public void drawableHotspotChanged(float x, float y) {
          if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
              if (mForeground != null) {
                  mForeground.setHotspot(x, y);
              }
          }
      }
  
  }