/*
 * Copyright (C) 2014 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.support.v17.leanback.widget;

import android.content.Context;
import android.content.res.TypedArray;
import android.support.v17.leanback.R;
import android.text.Layout;
import android.util.AttributeSet;
import android.util.TypedValue;
import android.widget.TextView;

/**
 * <p>A {@link android.widget.TextView} that adjusts text size automatically in response
 * to certain trigger conditions, such as text that wraps over multiple lines.</p>
 */
class ResizingTextView extends TextView {

    /**
     * Trigger text resize when text flows into the last line of a multi-line text view.
     */
    public static final int TRIGGER_MAX_LINES = 0x01;

    private int mTriggerConditions; // Union of trigger conditions
    private int mResizedTextSize;
    // Note: Maintaining line spacing turned out not to be useful, and will be removed in
    // the next round of design for this class (b/18736630). For now it simply defaults to false.
    private boolean mMaintainLineSpacing;
    private int mResizedPaddingAdjustmentTop;
    private int mResizedPaddingAdjustmentBottom;

    private boolean mIsResized = false;
    // Remember default properties in case we need to restore them
    private boolean mDefaultsInitialized = false;
    private int mDefaultTextSize;
    private float mDefaultLineSpacingExtra;
    private int mDefaultPaddingTop;
    private int mDefaultPaddingBottom;

    public ResizingTextView(Context ctx, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
        super(ctx, attrs, defStyleAttr);
        TypedArray a = ctx.obtainStyledAttributes(attrs, R.styleable.lbResizingTextView,
                defStyleAttr, defStyleRes);

        try {
            mTriggerConditions = a.getInt(
                    R.styleable.lbResizingTextView_resizeTrigger, TRIGGER_MAX_LINES);
            mResizedTextSize = a.getDimensionPixelSize(
                    R.styleable.lbResizingTextView_resizedTextSize, -1);
            mMaintainLineSpacing = a.getBoolean(
                    R.styleable.lbResizingTextView_maintainLineSpacing, false);
            mResizedPaddingAdjustmentTop = a.getDimensionPixelOffset(
                    R.styleable.lbResizingTextView_resizedPaddingAdjustmentTop, 0);
            mResizedPaddingAdjustmentBottom = a.getDimensionPixelOffset(
                    R.styleable.lbResizingTextView_resizedPaddingAdjustmentBottom, 0);
        } finally {
            a.recycle();
        }
    }

    public ResizingTextView(Context ctx, AttributeSet attrs, int defStyleAttr) {
        this(ctx, attrs, defStyleAttr, 0);
    }

    public ResizingTextView(Context ctx, AttributeSet attrs) {
        // TODO We should define our own style that inherits from TextViewStyle, to set defaults
        // for new styleables,  We then pass the appropriate R.attr up the constructor chain here.
        this(ctx, attrs, android.R.attr.textViewStyle);
    }

    public ResizingTextView(Context ctx) {
        this(ctx, null);
    }

    /**
     * @return the trigger conditions used to determine whether resize occurs
     */
    public int getTriggerConditions() {
        return mTriggerConditions;
    }

    /**
     * Set the trigger conditions used to determine whether resize occurs. Pass
     * a union of trigger condition constants, such as {@link ResizingTextView#TRIGGER_MAX_LINES}.
     *
     * @param conditions A union of trigger condition constants
     */
    public void setTriggerConditions(int conditions) {
        if (mTriggerConditions != conditions) {
            mTriggerConditions = conditions;
            // Always request a layout when trigger conditions change
            requestLayout();
        }
    }

    /**
     * @return the resized text size
     */
    public int getResizedTextSize() {
        return mResizedTextSize;
    }

    /**
     * Set the text size for resized text.
     *
     * @param size The text size for resized text
     */
    public void setResizedTextSize(int size) {
        if (mResizedTextSize != size) {
            mResizedTextSize = size;
            resizeParamsChanged();
        }
    }

    /**
     * @return whether or not to maintain line spacing when resizing text.
     * The default is true.
     */
    public boolean getMaintainLineSpacing() {
        return mMaintainLineSpacing;
    }

    /**
     * Set whether or not to maintain line spacing when resizing text.
     * The default is true.
     *
     * @param maintain Whether or not to maintain line spacing
     */
    public void setMaintainLineSpacing(boolean maintain) {
        if (mMaintainLineSpacing != maintain) {
            mMaintainLineSpacing = maintain;
            resizeParamsChanged();
        }
    }

    /**
     * @return desired adjustment to top padding for resized text
     */
    public int getResizedPaddingAdjustmentTop() {
        return mResizedPaddingAdjustmentTop;
    }

    /**
     * Set the desired adjustment to top padding for resized text.
     *
     * @param adjustment The adjustment to top padding, in pixels
     */
    public void setResizedPaddingAdjustmentTop(int adjustment) {
        if (mResizedPaddingAdjustmentTop != adjustment) {
            mResizedPaddingAdjustmentTop = adjustment;
            resizeParamsChanged();
        }
    }

    /**
     * @return desired adjustment to bottom padding for resized text
     */
    public int getResizedPaddingAdjustmentBottom() {
        return mResizedPaddingAdjustmentBottom;
    }

    /**
     * Set the desired adjustment to bottom padding for resized text.
     *
     * @param adjustment The adjustment to bottom padding, in pixels
     */
    public void setResizedPaddingAdjustmentBottom(int adjustment) {
        if (mResizedPaddingAdjustmentBottom != adjustment) {
            mResizedPaddingAdjustmentBottom = adjustment;
            resizeParamsChanged();
        }
    }

    private void resizeParamsChanged() {
        // If we're not resized, then changing resize parameters doesn't
        // affect layout, so don't bother requesting.
        if (mIsResized) {
            requestLayout();
        }
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        if (!mDefaultsInitialized) {
            mDefaultTextSize = (int) getTextSize();
            mDefaultLineSpacingExtra = getLineSpacingExtra();
            mDefaultPaddingTop = getPaddingTop();
            mDefaultPaddingBottom = getPaddingBottom();
            mDefaultsInitialized = true;
        }

        // Always try first to measure with defaults. Otherwise, we may think we can get away
        // with larger text sizes later when we actually can't.
        setTextSize(TypedValue.COMPLEX_UNIT_PX, mDefaultTextSize);
        setLineSpacing(mDefaultLineSpacingExtra, getLineSpacingMultiplier());
        setPaddingTopAndBottom(mDefaultPaddingTop, mDefaultPaddingBottom);

        super.onMeasure(widthMeasureSpec, heightMeasureSpec);

        boolean resizeText = false;

        final Layout layout = getLayout();
        if (layout != null) {
            if ((mTriggerConditions & TRIGGER_MAX_LINES) > 0) {
                final int lineCount = layout.getLineCount();
                final int maxLines = getMaxLines();
                if (maxLines > 1) {
                    resizeText = lineCount == maxLines;
                }
            }
        }

        final int currentSizePx = (int) getTextSize();
        boolean remeasure = false;
        if (resizeText) {
            if (mResizedTextSize != -1 && currentSizePx != mResizedTextSize) {
                setTextSize(TypedValue.COMPLEX_UNIT_PX, mResizedTextSize);
                remeasure = true;
            }
            // Check for other desired adjustments in addition to the text size
            final float targetLineSpacingExtra = mDefaultLineSpacingExtra
                    + mDefaultTextSize - mResizedTextSize;
            if (mMaintainLineSpacing && getLineSpacingExtra() != targetLineSpacingExtra) {
                setLineSpacing(targetLineSpacingExtra, getLineSpacingMultiplier());
                remeasure = true;
            }
            final int paddingTop = mDefaultPaddingTop + mResizedPaddingAdjustmentTop;
            final int paddingBottom = mDefaultPaddingBottom + mResizedPaddingAdjustmentBottom;
            if (getPaddingTop() != paddingTop || getPaddingBottom() != paddingBottom) {
                setPaddingTopAndBottom(paddingTop, paddingBottom);
                remeasure = true;
            }
        } else {
            // Use default size, line spacing, and padding
            if (mResizedTextSize != -1 && currentSizePx != mDefaultTextSize) {
                setTextSize(TypedValue.COMPLEX_UNIT_PX, mDefaultTextSize);
                remeasure = true;
            }
            if (mMaintainLineSpacing && getLineSpacingExtra() != mDefaultLineSpacingExtra) {
                setLineSpacing(mDefaultLineSpacingExtra, getLineSpacingMultiplier());
                remeasure = true;
            }
            if (getPaddingTop() != mDefaultPaddingTop
                    || getPaddingBottom() != mDefaultPaddingBottom) {
                setPaddingTopAndBottom(mDefaultPaddingTop, mDefaultPaddingBottom);
                remeasure = true;
            }
        }
        mIsResized = resizeText;
        if (remeasure) {
            super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        }
    }

    private void setPaddingTopAndBottom(int paddingTop, int paddingBottom) {
        if (isPaddingRelative()) {
            setPaddingRelative(getPaddingStart(), paddingTop, getPaddingEnd(), paddingBottom);
        } else {
            setPadding(getPaddingLeft(), paddingTop, getPaddingRight(), paddingBottom);
        }
    }
}
