content: /*
   * Copyright (C) 2017 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.setupwizardlib.template;
  
  import android.content.res.ColorStateList;
  import android.os.Build;
  import android.os.Build.VERSION_CODES;
  import androidx.annotation.Nullable;
  import android.view.View;
  import android.view.ViewStub;
  import android.widget.ProgressBar;
  import com.android.setupwizardlib.R;
  import com.android.setupwizardlib.TemplateLayout;
  
  /** A {@link Mixin} for showing a progress bar. */
  public class ProgressBarMixin implements Mixin {
  
    private final TemplateLayout templateLayout;
  
    @Nullable private ColorStateList color;
  
    /** @param layout The layout this mixin belongs to. */
    public ProgressBarMixin(TemplateLayout layout) {
      templateLayout = layout;
    }
  
    /** @return True if the progress bar is currently shown. */
    public boolean isShown() {
      final View progressBar = templateLayout.findManagedViewById(R.id.suw_layout_progress);
      return progressBar != null && progressBar.getVisibility() == View.VISIBLE;
    }
  
    /**
     * Sets whether the progress bar is shown. If the progress bar has not been inflated from the
     * stub, this method will inflate the progress bar.
     *
     * @param shown True to show the progress bar, false to hide it.
     */
    public void setShown(boolean shown) {
      if (shown) {
        View progressBar = getProgressBar();
        if (progressBar != null) {
          progressBar.setVisibility(View.VISIBLE);
        }
      } else {
        View progressBar = peekProgressBar();
        if (progressBar != null) {
          progressBar.setVisibility(View.GONE);
        }
      }
    }
  
    /**
     * Gets the progress bar in the layout. If the progress bar has not been used before, it will be
     * installed (i.e. inflated from its view stub).
     *
     * @return The progress bar of this layout. May be null only if the template used doesn't have a
     *     progress bar built-in.
     */
    private ProgressBar getProgressBar() {
      final View progressBar = peekProgressBar();
      if (progressBar == null) {
        final ViewStub progressBarStub =
            (ViewStub) templateLayout.findManagedViewById(R.id.suw_layout_progress_stub);
        if (progressBarStub != null) {
          progressBarStub.inflate();
        }
        setColor(color);
      }
      return peekProgressBar();
    }
  
    /**
     * Gets the progress bar in the layout only if it has been installed. {@link #setShown(boolean)}
     * should be called before this to ensure the progress bar is set up correctly.
     *
     * @return The progress bar of this layout, or null if the progress bar is not installed. The null
     *     case can happen either if {@link #setShown(boolean)} with true was not called before this,
     *     or if the template does not contain a progress bar.
     */
    public ProgressBar peekProgressBar() {
      return (ProgressBar) templateLayout.findManagedViewById(R.id.suw_layout_progress);
    }
  
    /** Sets the color of the indeterminate progress bar. This method is a no-op on SDK < 21. */
    public void setColor(@Nullable ColorStateList color) {
      this.color = color;
      if (Build.VERSION.SDK_INT >= VERSION_CODES.LOLLIPOP) {
        final ProgressBar bar = peekProgressBar();
        if (bar != null) {
          bar.setIndeterminateTintList(color);
          if (Build.VERSION.SDK_INT >= VERSION_CODES.M || color != null) {
            // There is a bug in Lollipop where setting the progress tint color to null
            // will crash with "java.lang.NullPointerException: Attempt to invoke virtual
            // method 'int android.graphics.Paint.getAlpha()' on a null object reference"
            // at android.graphics.drawable.NinePatchDrawable.draw(:250)
            // The bug doesn't affect ProgressBar on M because it uses ShapeDrawable instead
            // of NinePatchDrawable. (commit 6a8253fdc9f4574c28b4beeeed90580ffc93734a)
            bar.setProgressBackgroundTintList(color);
          }
        }
      }
    }
  
    /**
     * @return The color previously set in {@link #setColor(ColorStateList)}, or null if the color is
     *     not set. In case of null, the color of the progress bar will be inherited from the theme.
     */
    @Nullable
    public ColorStateList getColor() {
      return color;
    }
  }
  