/*
 * 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.text.Layout;
import android.util.AttributeSet;
import android.util.TypedValue;
import android.widget.TextView;

import android.support.v17.leanback.R;

/**
 * <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>
 * @hide
 */
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);
        }
    }
}
