/**
   * Converts a drawable to a tiled version of itself. It will recursively traverse layer and state
   * list drawables.
   */
  private Drawable tileify(Drawable drawable, boolean clip) {

    if (drawable instanceof LayerDrawable) {
      LayerDrawable background = (LayerDrawable) drawable;
      final int N = background.getNumberOfLayers();
      Drawable[] outDrawables = new Drawable[N];

      for (int i = 0; i < N; i++) {
        int id = background.getId(i);
        outDrawables[i] =
            tileify(
                background.getDrawable(i), (id == R.id.progress || id == R.id.secondaryProgress));
      }

      LayerDrawable newBg = new LayerDrawable(outDrawables);

      for (int i = 0; i < N; i++) {
        newBg.setId(i, background.getId(i));
      }

      return newBg;

    } else if (drawable instanceof StateListDrawable) {
      StateListDrawable in = (StateListDrawable) drawable;
      StateListDrawable out = new StateListDrawable();
      int numStates = in.getStateCount();
      for (int i = 0; i < numStates; i++) {
        out.addState(in.getStateSet(i), tileify(in.getStateDrawable(i), clip));
      }
      return out;

    } else if (drawable instanceof BitmapDrawable) {
      final Bitmap tileBitmap = ((BitmapDrawable) drawable).getBitmap();
      if (mSampleTile == null) {
        mSampleTile = tileBitmap;
      }

      final ShapeDrawable shapeDrawable = new ShapeDrawable(getDrawableShape());

      final BitmapShader bitmapShader =
          new BitmapShader(tileBitmap, Shader.TileMode.REPEAT, Shader.TileMode.CLAMP);
      shapeDrawable.getPaint().setShader(bitmapShader);

      return (clip)
          ? new ClipDrawable(shapeDrawable, Gravity.LEFT, ClipDrawable.HORIZONTAL)
          : shapeDrawable;
    }

    return drawable;
  }