/*
 * Copyright (C) 2006 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 android.widget;

import android.annotation.NonNull;
import android.annotation.Nullable;
import android.compat.annotation.UnsupportedAppUsage;
import android.graphics.Canvas;
import android.graphics.ColorFilter;
import android.graphics.PixelFormat;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
import android.os.Build;
import android.view.View;

import com.android.internal.widget.ScrollBarUtils;

/**
 * This is only used by View for displaying its scroll bars. It should probably
 * be moved in to the view package since it is used in that lower-level layer.
 * For now, we'll hide it so it can be cleaned up later.
 *
 * {@hide}
 */
public class ScrollBarDrawable extends Drawable implements Drawable.Callback {
    private Drawable mVerticalTrack;
    private Drawable mHorizontalTrack;
    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 123768422)
    private Drawable mVerticalThumb;
    private Drawable mHorizontalThumb;

    private int mRange;
    private int mOffset;
    private int mExtent;

    private boolean mVertical;
    private boolean mBoundsChanged;
    private boolean mRangeChanged;
    private boolean mAlwaysDrawHorizontalTrack;
    private boolean mAlwaysDrawVerticalTrack;
    private boolean mMutated;

    private int mAlpha = 255;
    private boolean mHasSetAlpha;

    private ColorFilter mColorFilter;
    private boolean mHasSetColorFilter;

    @UnsupportedAppUsage
    public ScrollBarDrawable() {
    }

    /**
     * Indicate whether the horizontal scrollbar track should always be drawn
     * regardless of the extent. Defaults to false.
     *
     * @param alwaysDrawTrack Whether the track should always be drawn
     *
     * @see #getAlwaysDrawHorizontalTrack()
     */
    public void setAlwaysDrawHorizontalTrack(boolean alwaysDrawTrack) {
        mAlwaysDrawHorizontalTrack = alwaysDrawTrack;
    }

    /**
     * Indicate whether the vertical scrollbar track should always be drawn
     * regardless of the extent. Defaults to false.
     *
     * @param alwaysDrawTrack Whether the track should always be drawn
     *
     * @see #getAlwaysDrawVerticalTrack()
     */
    public void setAlwaysDrawVerticalTrack(boolean alwaysDrawTrack) {
        mAlwaysDrawVerticalTrack = alwaysDrawTrack;
    }

    /**
     * @return whether the vertical scrollbar track should always be drawn
     *         regardless of the extent.
     *
     * @see #setAlwaysDrawVerticalTrack(boolean)
     */
    public boolean getAlwaysDrawVerticalTrack() {
        return mAlwaysDrawVerticalTrack;
    }

    /**
     * @return whether the horizontal scrollbar track should always be drawn
     *         regardless of the extent.
     *
     * @see #setAlwaysDrawHorizontalTrack(boolean)
     */
    public boolean getAlwaysDrawHorizontalTrack() {
        return mAlwaysDrawHorizontalTrack;
    }

    public void setParameters(int range, int offset, int extent, boolean vertical) {
        if (mVertical != vertical) {
            mVertical = vertical;

            mBoundsChanged = true;
        }

        if (mRange != range || mOffset != offset || mExtent != extent) {
            mRange = range;
            mOffset = offset;
            mExtent = extent;

            mRangeChanged = true;
        }
    }

    @Override
    public void draw(Canvas canvas) {
        final boolean vertical = mVertical;
        final int extent = mExtent;
        final int range = mRange;

        boolean drawTrack = true;
        boolean drawThumb = true;
        if (extent <= 0 || range <= extent) {
            drawTrack = vertical ? mAlwaysDrawVerticalTrack : mAlwaysDrawHorizontalTrack;
            drawThumb = false;
        }

        final Rect r = getBounds();
        if (canvas.quickReject(r.left, r.top, r.right, r.bottom, Canvas.EdgeType.AA)) {
            return;
        }

        if (drawTrack) {
            drawTrack(canvas, r, vertical);
        }

        if (drawThumb) {
            final int scrollBarLength = vertical ? r.height() : r.width();
            final int thickness = vertical ? r.width() : r.height();
            final int thumbLength =
                    ScrollBarUtils.getThumbLength(scrollBarLength, thickness, extent, range);
            final int thumbOffset =
                    ScrollBarUtils.getThumbOffset(scrollBarLength, thumbLength, extent, range,
                            mOffset);

            drawThumb(canvas, r, thumbOffset, thumbLength, vertical);
        }
    }

    @Override
    protected void onBoundsChange(Rect bounds) {
        super.onBoundsChange(bounds);
        mBoundsChanged = true;
    }

    @Override
    public boolean isStateful() {
        return (mVerticalTrack != null && mVerticalTrack.isStateful())
                || (mVerticalThumb != null && mVerticalThumb.isStateful())
                || (mHorizontalTrack != null && mHorizontalTrack.isStateful())
                || (mHorizontalThumb != null && mHorizontalThumb.isStateful())
                || super.isStateful();
    }

    @Override
    protected boolean onStateChange(int[] state) {
        boolean changed = super.onStateChange(state);
        if (mVerticalTrack != null) {
            changed |= mVerticalTrack.setState(state);
        }
        if (mVerticalThumb != null) {
            changed |= mVerticalThumb.setState(state);
        }
        if (mHorizontalTrack != null) {
            changed |= mHorizontalTrack.setState(state);
        }
        if (mHorizontalThumb != null) {
            changed |= mHorizontalThumb.setState(state);
        }
        return changed;
    }

    private void drawTrack(Canvas canvas, Rect bounds, boolean vertical) {
        final Drawable track;
        if (vertical) {
            track = mVerticalTrack;
        } else {
            track = mHorizontalTrack;
        }

        if (track != null) {
            if (mBoundsChanged) {
                track.setBounds(bounds);
            }
            track.draw(canvas);
        }
    }

    private void drawThumb(Canvas canvas, Rect bounds, int offset, int length, boolean vertical) {
        final boolean changed = mRangeChanged || mBoundsChanged;
        if (vertical) {
            if (mVerticalThumb != null) {
                final Drawable thumb = mVerticalThumb;
                if (changed) {
                    thumb.setBounds(bounds.left, bounds.top + offset,
                            bounds.right, bounds.top + offset + length);
                }

                thumb.draw(canvas);
            }
        } else {
            if (mHorizontalThumb != null) {
                final Drawable thumb = mHorizontalThumb;
                if (changed) {
                    thumb.setBounds(bounds.left + offset, bounds.top,
                            bounds.left + offset + length, bounds.bottom);
                }

                thumb.draw(canvas);
            }
        }
    }

    /**
     * @see android.view.View#setVerticalThumbDrawable(Drawable)
     */
    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P)
    public void setVerticalThumbDrawable(Drawable thumb) {
        if (mVerticalThumb != null) {
            mVerticalThumb.setCallback(null);
        }

        propagateCurrentState(thumb);
        mVerticalThumb = thumb;
    }

    /**
     * @see View#getVerticalTrackDrawable()
     */
    public @Nullable Drawable getVerticalTrackDrawable() {
        return mVerticalTrack;
    }

    /**
     * @see View#getVerticalThumbDrawable()
     */
    public @Nullable Drawable getVerticalThumbDrawable() {
        return mVerticalThumb;
    }

    /**
     * @see View#getHorizontalTrackDrawable()
     */
    public @Nullable Drawable getHorizontalTrackDrawable() {
        return mHorizontalTrack;
    }

    /**
     * @see View#getHorizontalThumbDrawable()
     */
    public @Nullable Drawable getHorizontalThumbDrawable() {
        return mHorizontalThumb;
    }

    /**
     * @see android.view.View#setVerticalTrackDrawable(Drawable)
     */
    public void setVerticalTrackDrawable(Drawable track) {
        if (mVerticalTrack != null) {
            mVerticalTrack.setCallback(null);
        }

        propagateCurrentState(track);
        mVerticalTrack = track;
    }

    /**
     * @see android.view.View#setHorizontalThumbDrawable(Drawable)
     */
    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P)
    public void setHorizontalThumbDrawable(Drawable thumb) {
        if (mHorizontalThumb != null) {
            mHorizontalThumb.setCallback(null);
        }

        propagateCurrentState(thumb);
        mHorizontalThumb = thumb;
    }

    public void setHorizontalTrackDrawable(Drawable track) {
        if (mHorizontalTrack != null) {
            mHorizontalTrack.setCallback(null);
        }

        propagateCurrentState(track);
        mHorizontalTrack = track;
    }

    private void propagateCurrentState(Drawable d) {
        if (d != null) {
            if (mMutated) {
                d.mutate();
            }

            d.setState(getState());
            d.setCallback(this);

            if (mHasSetAlpha) {
                d.setAlpha(mAlpha);
            }

            if (mHasSetColorFilter) {
                d.setColorFilter(mColorFilter);
            }
        }
    }

    public int getSize(boolean vertical) {
        if (vertical) {
            return mVerticalTrack != null ? mVerticalTrack.getIntrinsicWidth() :
                    mVerticalThumb != null ? mVerticalThumb.getIntrinsicWidth() : 0;
        } else {
            return mHorizontalTrack != null ? mHorizontalTrack.getIntrinsicHeight() :
                    mHorizontalThumb != null ? mHorizontalThumb.getIntrinsicHeight() : 0;
        }
    }

    @Override
    public ScrollBarDrawable mutate() {
        if (!mMutated && super.mutate() == this) {
            if (mVerticalTrack != null) {
                mVerticalTrack.mutate();
            }
            if (mVerticalThumb != null) {
                mVerticalThumb.mutate();
            }
            if (mHorizontalTrack != null) {
                mHorizontalTrack.mutate();
            }
            if (mHorizontalThumb != null) {
                mHorizontalThumb.mutate();
            }
            mMutated = true;
        }
        return this;
    }

    @Override
    public void setAlpha(int alpha) {
        mAlpha = alpha;
        mHasSetAlpha = true;

        if (mVerticalTrack != null) {
            mVerticalTrack.setAlpha(alpha);
        }
        if (mVerticalThumb != null) {
            mVerticalThumb.setAlpha(alpha);
        }
        if (mHorizontalTrack != null) {
            mHorizontalTrack.setAlpha(alpha);
        }
        if (mHorizontalThumb != null) {
            mHorizontalThumb.setAlpha(alpha);
        }
    }

    @Override
    public int getAlpha() {
        return mAlpha;
    }

    @Override
    public void setColorFilter(ColorFilter colorFilter) {
        mColorFilter = colorFilter;
        mHasSetColorFilter = true;

        if (mVerticalTrack != null) {
            mVerticalTrack.setColorFilter(colorFilter);
        }
        if (mVerticalThumb != null) {
            mVerticalThumb.setColorFilter(colorFilter);
        }
        if (mHorizontalTrack != null) {
            mHorizontalTrack.setColorFilter(colorFilter);
        }
        if (mHorizontalThumb != null) {
            mHorizontalThumb.setColorFilter(colorFilter);
        }
    }

    @Override
    public ColorFilter getColorFilter() {
        return mColorFilter;
    }

    @Override
    public int getOpacity() {
        return PixelFormat.TRANSLUCENT;
    }

    @Override
    public void invalidateDrawable(@NonNull Drawable who) {
        invalidateSelf();
    }

    @Override
    public void scheduleDrawable(@NonNull Drawable who, @NonNull Runnable what, long when) {
        scheduleSelf(what, when);
    }

    @Override
    public void unscheduleDrawable(@NonNull Drawable who, @NonNull Runnable what) {
        unscheduleSelf(what);
    }

    @Override
    public String toString() {
        return "ScrollBarDrawable: range=" + mRange + " offset=" + mOffset +
               " extent=" + mExtent + (mVertical ? " V" : " H");
    }
}


