content: /*
   * Copyright (C) 2016 Bilibili
   *
   * 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.bilibili.magicasakura.widgets;
  
  import android.content.res.TypedArray;
  import android.graphics.PorterDuff;
  import android.graphics.drawable.Drawable;
  import android.os.Build;
  import android.support.v4.content.ContextCompat;
  import android.support.v4.graphics.drawable.DrawableCompat;
  import android.util.AttributeSet;
  import android.view.View;
  
  import com.bilibili.magicasakura.utils.DrawableUtils;
  import com.bilibili.magicasakura.utils.ThemeUtils;
  import com.bilibili.magicasakura.utils.TintInfo;
  import com.bilibili.magicasakura.utils.TintManager;
  import com.wm.remusic.R;
  
  /**
   * @author xyczero617@gmail.com
   * @time 15/9/26
   */
  public class AppCompatBackgroundHelper extends AppCompatBaseHelper {
  
      private static final int[] ATTR = {
              android.R.attr.background,
              R.attr.backgroundTint,
              R.attr.backgroundTintMode
      };
  
      private TintInfo mBackgroundTintInfo;
  
      private int mBackgroundResId;
      private int mBackgroundTintResId;
  
      private int mPaddingLeft, mPaddingTop, mPaddingRight, mPaddingBottom;
  
      public AppCompatBackgroundHelper(View view, TintManager tintManager) {
          super(view, tintManager);
      }
  
      @SuppressWarnings("ResourceType")
      @Override
      void loadFromAttribute(AttributeSet attrs, int defStyleAttr) {
          initPadding();
          TypedArray array = mView.getContext().obtainStyledAttributes(attrs, ATTR, defStyleAttr, 0);
          if (array.hasValue(1)) {
              mBackgroundTintResId = array.getResourceId(1, 0);
              if (array.hasValue(2)) {
                  setSupportBackgroundTintMode(DrawableUtils.parseTintMode(array.getInt(2, 0), null));
              }
              setSupportBackgroundTint(mBackgroundTintResId);
          } else {
              Drawable drawable = mTintManager.getDrawable(mBackgroundResId = array.getResourceId(0, 0));
              if (drawable != null) {
                  setBackgroundDrawable(drawable);
              }
          }
          array.recycle();
      }
  
      /**
       * External use
       *
       * @param background
       */
      public void setBackgroundDrawableExternal(Drawable background) {
          if (skipNextApply()) return;
  
          resetTintResource(0);
          setSkipNextApply(false);
          recoverPadding(background);
      }
  
      public void setBackgroundColor(int color) {
          if (skipNextApply()) return;
  
          resetTintResource(0);
          mView.setBackgroundColor(ThemeUtils.getColor(mView.getContext(), color));
      }
  
      public void setBackgroundResId(int resId) {
          if (mBackgroundResId != resId) {
              resetTintResource(resId);
  
              if (resId != 0) {
                  Drawable drawable = mTintManager.getDrawable(resId);
                  setBackgroundDrawable(
                          drawable != null ? drawable : ContextCompat.getDrawable(mView.getContext(), resId));
              }
          }
      }
  
      public void setBackgroundTintList(int resId, PorterDuff.Mode mode) {
          if (mBackgroundTintResId != resId) {
              mBackgroundTintResId = resId;
              if (mBackgroundTintInfo != null) {
                  mBackgroundTintInfo.mHasTintList = false;
                  mBackgroundTintInfo.mTintList = null;
              }
              setSupportBackgroundTintMode(mode);
              setSupportBackgroundTint(resId);
          }
      }
  
      /**
       * Internal use
       */
      private void setBackgroundDrawable(Drawable drawable) {
          if (skipNextApply()) return;
  
          setBackground(drawable);
          recoverPadding(drawable);
      }
  
      private boolean setSupportBackgroundTint(int resId) {
          if (resId != 0) {
              if (mBackgroundTintInfo == null) {
                  mBackgroundTintInfo = new TintInfo();
              }
              mBackgroundTintInfo.mHasTintList = true;
              mBackgroundTintInfo.mTintList = mTintManager.getColorStateList(resId);
          }
          return applySupportBackgroundTint();
      }
  
      private void setSupportBackgroundTintMode(PorterDuff.Mode mode) {
          if (mBackgroundTintResId != 0 && mode != null) {
              if (mBackgroundTintInfo == null) {
                  mBackgroundTintInfo = new TintInfo();
              }
              mBackgroundTintInfo.mHasTintMode = true;
              mBackgroundTintInfo.mTintMode = mode;
          }
      }
  
      private boolean applySupportBackgroundTint() {
          Drawable backgroundDrawable = mView.getBackground();
          if (backgroundDrawable != null && mBackgroundTintInfo != null && mBackgroundTintInfo.mHasTintList) {
              backgroundDrawable = DrawableCompat.wrap(backgroundDrawable);
              backgroundDrawable = backgroundDrawable.mutate();
              if (mBackgroundTintInfo.mHasTintList) {
                  DrawableCompat.setTintList(backgroundDrawable, mBackgroundTintInfo.mTintList);
              }
              if (mBackgroundTintInfo.mHasTintMode) {
                  DrawableCompat.setTintMode(backgroundDrawable, mBackgroundTintInfo.mTintMode);
              }
              if (backgroundDrawable.isStateful()) {
                  backgroundDrawable.setState(mView.getDrawableState());
              }
              setBackgroundDrawable(backgroundDrawable);
              return true;
          }
          return false;
      }
  
      private void setBackground(Drawable backgroundDrawable) {
          if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN) {
              mView.setBackgroundDrawable(backgroundDrawable);
          } else {
              mView.setBackground(backgroundDrawable);
          }
      }
  
      private void resetTintResource(int resId/*background resource id*/) {
          mBackgroundResId = resId;
          mBackgroundTintResId = 0;
          if (mBackgroundTintInfo != null) {
              mBackgroundTintInfo.mHasTintList = false;
              mBackgroundTintInfo.mTintList = null;
              mBackgroundTintInfo.mHasTintMode = false;
              mBackgroundTintInfo.mTintMode = null;
          }
      }
  
      private void initPadding() {
          mPaddingLeft = mView.getPaddingLeft();
          mPaddingTop = mView.getPaddingTop();
          mPaddingRight = mView.getPaddingRight();
          mPaddingBottom = mView.getPaddingBottom();
      }
  
      private boolean hasPadding() {
          return mPaddingLeft != 0 || mPaddingRight != 0 || mPaddingTop != 0 || mPaddingBottom != 0;
      }
  
      private void recoverPadding(Drawable background) {
          if (ThemeUtils.containsNinePatch(background) && hasPadding()) {
              mView.setPadding(mPaddingLeft, mPaddingTop, mPaddingRight, mPaddingBottom);
          }
      }
  
      @Override
      public void tint() {
          if (mBackgroundTintResId == 0 || !setSupportBackgroundTint(mBackgroundTintResId)) {
              Drawable drawable = mTintManager.getDrawable(mBackgroundResId);
              if (drawable == null) {
                  drawable = mBackgroundResId == 0 ? null : ContextCompat.getDrawable(mView.getContext(), mBackgroundResId);
              }
              setBackgroundDrawable(drawable);
          }
      }
  
      public interface BackgroundExtensible {
          void setBackgroundTintList(int resId);
  
          void setBackgroundTintList(int resId, PorterDuff.Mode mode);
      }
  }
  